Typescript为任意数量的参数编写zip函数类型声明



我写了一个迭代器类和一个方法来压缩两个迭代器,它接受一个参数,它的类型声明看起来像这样:

zip<B>(other: Iterable<B> | Iterator<B>): ItIterator<[T, B]>

其中Tthis.next().value的类型。

但是我不知道怎么写它所以它接受任意数量的参数并返回元组上的迭代器,这样

ItIterator.prototype.zip.call([1][Symbol.iterator](), ['a'], [false])

将返回ItIterator<[number, string, boolean]>

有办法做到这一点吗?

我将采用以下方法:

declare class ItIterator<T> {
zip<B extends any[]>(
...other: { [I in keyof B]: Iterable<B[I]> | Iterator<B[I]> }
): ItIterator<[T, ...B]>;
}

这个想法是zip()B的泛型,other可迭代对象的元素类型的元组类型。我的意思是,如果你调用zip(x, y, z),其中xIterable<X>,yIterable<Y>,zIterable<Z>,那么类型参数B将是[X, Y, Z]

这是通过让other的其余参数元组类型是B的映射元组类型来实现的。

则输出类型为可变元组类型[T, ...B]ItIterator<>,其中将T添加到B的元组中。


让我们测试一下:

declare const i: ItIterator<string>;
const y = i.zip([1], [true], [new Date(), new Date()]);
// const y: ItIterator<[string, number, boolean, Date]>

看起来不错。注意,我不会尝试支持

const z = ItIterator.prototype.zip.call([1][Symbol.iterator](), ['a'], [false]);
// const z: ItIterator<[any, ...any[]]>

,因为函数的call()方法的类型支持不能很好地与本身是泛型的函数一起工作,并且您最终得到的只是ItIterator<[any, ...any[]]>的约束。

Playground链接到代码

最新更新