TypeScript中zip2函数的泛型类型推断逻辑解析
解析TypeScript zip2函数的泛型推断流程
先明确zip2的核心定义:
type Iterables<T> = { [K in keyof T]: Iterable<T[K]> }; type ZipItem<T> = { [K in keyof T]: T[K] | undefined }; function* zip2<T extends any[]>(...args: Iterables<T>): Generator<ZipItem<T>> {}
泛型推断的完整步骤可拆解为3个核心阶段:
1. 触发泛型推断:函数参数匹配
当调用zip2时(比如zip2([1,2,3], ['a','b'])),编译器会获取传入实参的类型:[number[], string[]](数组本身属于Iterable类型)。
此时函数形参类型为Iterables<T>,编译器需要找到符合T extends any[]约束的类型,让Iterables<T>与实参类型完全匹配。
2. 从Iterables<T>反向推导泛型T
Iterables<T>的作用是将T的每个元素类型包装为对应的Iterable类型,编译器会逆向执行这个逻辑:
- 对实参的每个位置
K,提取该位置Iterable的内部元素类型(比如实参第一个位置是Iterable<number>,提取出number;第二个位置是Iterable<string>,提取出string)。 - 将这些提取出的类型按顺序组合成数组类型,就是最终推断出的
T。
以上述调用为例,编译器会推断出T = [number, string]。
3. 用推断出的T生成返回类型
得到T后,编译器将其代入ZipItem<T>的定义:
ZipItem<T>会给T的每个元素类型添加undefined(因为zip逻辑会在最短的Iterable耗尽后,为后续位置补undefined)。- 代入
T = [number, string]后,得到[number | undefined, string | undefined],这就是返回的Generator的产出元组类型。
为何与zip1返回类型一致?
zip1的IterablesTuple<T>是直接对输入的Iterable数组T,提取每个元素的内部类型并添加undefined;而zip2是先推断出内部元素类型组成的T,再生成带undefined的数组类型,两者最终的类型结构完全等价,因此调用时返回的Generator类型一致。
内容的提问来源于stack exchange,提问作者Robert Kajic
相关产品推荐
相关产品推荐

