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

sqyvllje  于 2023-01-14  发布在  TypeScript
关注(0)|答案(1)|浏览(167)

我写了一个迭代器类和一个压缩两个迭代器的方法,它有一个参数,类型声明如下:

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]>
有什么办法吗?

wwtsj6pe

wwtsj6pe1#

我会采取以下方法:

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

其思想是zip()B中的genericother可迭代对象的元素类型的元组类型,我的意思是,如果你调用zip(x, y, z),其中xIterable<X>yIterable<Y>zIterable<Z>,则类型自变量B将是[X, Y, Z]
这是通过使other的rest参数元组类型成为B上的Map元组类型来实现的。
那么输出类型是可变元组类型[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代码链接

相关问题