我写了一个迭代器类和一个方法来压缩两个迭代器,它接受一个参数,它的类型声明看起来像这样:
zip<B>(other: Iterable<B> | Iterator<B>): ItIterator<[T, B]>
其中T
为this.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)
,其中x
是Iterable<X>
,y
是Iterable<Y>
,z
是Iterable<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链接到代码