在TypeScript中实现保留类型的可变参数zip迭代器
实现带类型保留的可变参数zip生成器函数
你可以通过TypeScript的泛型映射类型和条件类型推断来实现保留类型信息的可变参数zip函数,下面是完整的实现和类型说明:
完整代码
function* naturals(max = 10) { for (let i = 0; i < max; i++) yield i; } const x = [1, 2, 3]; const y = ["a", "b", "c"]; // 带类型保留的zip生成器函数 function* zip<T extends Iterable<any>[]>( ...iterables: T ): Generator<{ [K in keyof T]: T[K] extends Iterable<infer U> ? U : never }, void, undefined> { const iterators = iterables.map(iter => iter[Symbol.iterator]()); while (true) { const results = iterators.map(it => it.next()); // 只要有一个迭代器完成,就终止循环 if (results.some(res => res.done)) break; // 断言类型匹配映射后的元组类型 yield results.map(res => res.value) as { [K in keyof T]: T[K] extends Iterable<infer U> ? U : never }; } } const zipped = zip(naturals(), x, y); console.log([...zipped]); // 输出 [[0, 1, "a"], [1, 2, "b"], [2, 3, "c"]]
类型签名解析
泛型约束:
T extends Iterable<any>[]
约束传入的所有参数必须是可迭代对象(数组、生成器、Set等实现了Symbol.iterator的对象),让TypeScript能自动推断每个输入可迭代对象的具体类型。返回值类型:
Generator<映射类型, void, undefined>- 第一个参数是yield的元素类型:通过
{ [K in keyof T]: T[K] extends Iterable<infer U> ? U : never }遍历泛型T的每个元素,用infer U提取每个可迭代对象的元素类型,最终生成对应位置元素类型的元组。 - 后两个参数分别指定生成器的return值类型(
void表示无返回值)和next()方法的入参类型(undefined表示无需传参)。
- 第一个参数是yield的元素类型:通过
类型保留效果
调用zip(naturals(), x, y)时,TypeScript会自动推断:
- 输入泛型T为
[Generator<number, void, undefined>, number[], string[]] - yield的元素类型为
[number, number, string] - 变量
zipped的类型为Generator<[number, number, string], void, undefined>,展开后的数组类型为[number, number, string][],完全保留了输入可迭代对象的类型信息。
内容的提问来源于stack exchange,提问作者Meow
相关产品推荐
相关产品推荐

