我正在尝试在可迭代对象上编写可变参数 zip,同时保留类型。例如,
function* naturals(max=10) { for (let i=0; i<max; i++) yield i }
const x = [1, 2, 3]
const y = ["a", "b", "c"]
const zipped = zip(naturals(), x, y)
console.log([...zipped]) // => [[0, 1, "a"], [1, 2, "b"], [2, 3, "c"]]
function* zip<?>(...iterables:?[]) {
const iterators = iterables.map(iter => iter[Symbol.iterator]())
...
}
是否有类型签名可以帮助保留我的类型?
您可以给
zip()
以下呼叫签名:
declare function zip<T extends any[]>(
...iterables: { [I in keyof T]: Iterable<T[I]> }
): Iterable<T>;
类型参数 T
中的
generic表示输出中每个元素中数组的类型(即函数返回
Iterable<T>
)。这预计是一个元组类型。
输入类型是数组/元组类型T
上映射类型的
剩余参数,其中
T
的每个元素都包裹在Iterable
中。这种映射类型是 同态(具有 in keyof T
,请参阅 “同态映射类型”是什么意思? 了解更多信息),因此 TypeScript 可以从中推断出 T
。
让我们在您的示例中尝试一下:
const zipped = zip(naturals(), x, y)
// const zipped: Iterable<[number, number, string]>
此处
iterables
是可分配给 [Iterable<number>, Iterable<number>, Iterable<string>]
的元组类型,因此编译器将 T
推断为 [number, number, string]
。所以输出类型是预期的Iterable<[number, number, string]>
。