TypeScript Academy · 课时

类型级加法与减法

通过操作元组构建算术运算。

第 2 / 4 课13 个步骤

类型级加法与减法 是 CoddyKit 上的免费 TypeScript Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 TypeScript Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 TypeScript Academy 课程共包含 4 节课。

通过长度进行算术运算

采用元组长度表示法后,加法就变成拼接,减法就变成移除前缀。您可以在元组上进行计算,然后读取结果的长度。

type BuildTuple<N extends number, Acc extends unknown[] = []> =
  Acc["length"] extends N ? Acc : BuildTuple<N, [...Acc, unknown]>;

加法

要计算 A + B:构建长度为 A 的元组,再构建长度为 B 的元组,将两者展开到一个新元组中,然后读取它的长度。

type Add<A extends number, B extends number> =
  [...BuildTuple<A>, ...BuildTuple<B>]["length"];

type S = Add<3, 4>; // 7

为什么拼接可以实现加法

长度为 3 的元组后面接上长度为 4 的元组,会得到长度为 7 的元组。将两个计数标记中的标记合并,就得到了一个合计标记,因此长度也会相加。

type A = Add<2, 2>; // 4
type B = Add<0, 5>; // 5
type C = Add<1, 6>; // 7

通过前缀进行减法

要计算 A - B:构建长度为 A 的元组,然后将它推断为一个长度为 B 的前缀,后面跟着剩余部分。rest 的长度就是 A - B。

type Sub<A extends number, B extends number> =
  BuildTuple<A> extends [...BuildTuple<B>, ...infer Rest]
    ? Rest["length"]
    : never;

type D = Sub<7, 4>; // 3

逐步执行减法

对于 Sub<7, 4>:构建长度为 7 的元组,匹配长度为 4 的前缀,捕获 Rest(长度为 3),然后读取它的长度。移除的前缀正好包含 B 个标记。

type A = Sub<5, 2>; // 3
type B = Sub<4, 4>; // 0

下溢时返回无值类型

这里的类型级数字是非负的。如果 B > A,就不存在有效的前缀,模式匹配失败,结果为 never。如果您愿意,也可以将其默认设为 0。

type A = Sub<2, 5>; // never

type SubSafe<A extends number, B extends number> =
  [Sub<A, B>] extends [never] ? 0 : Sub<A, B>;
type B = SubSafe<2, 5>; // 0

递增与递减

加一和减一是加法与减法中非常常见的特殊情况,因此通常会为它们命名。Inc 添加一个元素;Dec 移除一个元素。

type Inc<N extends number> = [...BuildTuple<N>, unknown]["length"];
type Dec<N extends number> =
  BuildTuple<N> extends [unknown, ...infer R] ? R["length"] : 0;

type A = Inc<4>; // 5
type B = Dec<4>; // 3

通过重复实现乘法

乘法就是重复加法。通过使用 Dec 倒计数,并使用 Add 累加,将 B 加到累加器中 A 次。

type Mul<A extends number, B extends number, Acc extends number = 0> =
  A extends 0 ? Acc : Mul<Dec<A>, B, Add<Acc, B>>;

type A = Mul<3, 4>; // 12

BuildTuple 辅助工具

这里的每个操作都依赖于 BuildTuple。它是唯一可复用的基本工具:给定一个数字,就能得到对应长度的元组。请将它集中放在一个位置,并在其基础上构建其他功能。

type Five = BuildTuple<5>; // [unknown, unknown, unknown, unknown, unknown]
type N = Five["length"];   // 5

组合操作

由于每个操作都接收并返回数字,因此可以自由组合。您可以编写 Add<Mul<2, 3>, 4> 这样的表达式,编译器会对其求值。

type Result = Add<Mul<2, 3>, 4>; // 10

实际使用时的注意事项

这些技巧非常适合较小的数量:数组索引、固定大小、有限范围。对于较大的数字或通用数学运算,递归限制以及无法处理负数会使它们不实用。请在值保持较小且静态时使用它们。

type A = Add<8, 7>;  // 15 (fine)
// Add<5000, 5000> would exceed recursion limits

快速检查

请检验您对类型级算术的理解。

回顾

您已经在类型系统中实现了算术运算。

  • Add:拼接元组,读取长度。
  • Sub:推断前缀,读取剩余部分的长度。
  • Inc/Dec 是单步版本。
  • BuildTuple 是共享的基本工具。

下一步:在类型级别比较数字。

免费开始

用 AI 导师学习 TypeScript — 免费

在浏览器中编写并运行真实代码,获得全天候 AI 导师的即时帮助,并在网页或应用中继续学习。

课程
101
课程
352

常见问题解答

「类型级加法与减法」课时是免费的吗?

是的 — 「类型级加法与减法」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 TypeScript Academy 课程的其余内容,请升级到 CoddyKit PRO。 TypeScript Academy 课程共包含 4 节课。

「类型级加法与减法」这节课中我会学到什么?

通过操作元组构建算术运算。 你通过在浏览器中直接运行的动手代码来练习 TypeScript Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 TypeScript Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 TypeScript Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「类型级加法与减法」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 TypeScript Academy 课中编写并运行代码吗?

能。每节 TypeScript Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. 使用元组长度计数
  2. 类型级加法与减法
  3. 类型级比较
  4. 实用数字类型工具
← 返回 TypeScript Academy