You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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"]]

类型签名解析

  1. 泛型约束:T extends Iterable<any>[]
    约束传入的所有参数必须是可迭代对象(数组、生成器、Set等实现了Symbol.iterator的对象),让TypeScript能自动推断每个输入可迭代对象的具体类型。

  2. 返回值类型:Generator<映射类型, void, undefined>

    • 第一个参数是yield的元素类型:通过{ [K in keyof T]: T[K] extends Iterable<infer U> ? U : never }遍历泛型T的每个元素,用infer U提取每个可迭代对象的元素类型,最终生成对应位置元素类型的元组。
    • 后两个参数分别指定生成器的return值类型(void表示无返回值)和next()方法的入参类型(undefined表示无需传参)。

类型保留效果

调用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.04 18:02:20