类型级加法与减法
通过操作元组构建算术运算。
类型级加法与减法 是 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>; // 12BuildTuple 辅助工具
这里的每个操作都依赖于 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 反馈 — 无需本地设置。