gpt4 book ai didi

javascript - 在 typescript 中遍历可变元组

转载 作者:行者123 更新时间:2023-12-04 13:27:21 25 4
gpt4 key购买 nike

编辑:这个功能是作为 TypeScript 4.1 的一部分提供的,就像提到的 @jcalz 一样。
我想做一个通用类型,它接受一个元组并遍历它。我的第一种方法是递归,但我得到了 Type alias 'YourOperator' circularly references itself. .这是我尝试的最简单示例

type VariadicAnd<T extends any[]> = T extends [infer Head, ...infer Tail] ? Head & VariadicAnd<Tail> : unknown
在我的具体情况下,我还想转换 Head通过将它传递到另一个泛型类型中。例如:
type SimpleTransform<T> = { wrapped: T }
type VariadicAndWithTransform<T extends any[]> = T extends [infer Head, ...infer Tail]
? SimpleTransform<Head> & VariadicAndWithTransform<Tail>
: unknown;
有趣的是,我的 IntelliSence 正在正确解析类型,但 typescript 编译器拒绝接受它。我想知道是否有另一种方法,或者是否有办法使我的递归工作。

最佳答案

如上所述,在引入对 recursive conditional types 的支持后,您的版本在 TypeScript 4.1 及更高版本中按原样运行。 .

type VariadicAndWithTransform<T extends any[]> = T extends [infer F, ...infer R]
? SimpleTransform<F> & VariadicAndWithTransform<R>
: unknown; // no error

type Works = VariadicAndWithTransform<[{ a: 1 }, { b: 2 }, { c: 3 }]>;
/* type Works = SimpleTransform<{
a: 1;
}> & SimpleTransform<{
b: 2;
}> & SimpleTransform<{
c: 3;
}> */
有一些变通方法可以诱使编译器允许 4.1 之前的类型,但它们不受官方支持。如果你需要递归条件类型,你应该升级你的 TypeScript 版本。

但是对于此处所需的类型函数,您不需要递归类型。这实际上是一件好事,因为递归类型对编译器的负担更大,并且递归限制相当浅。如果你使用以上版本的 VariadicAndWithTransform<T>哪里 T有几十个元素,即使在 TS4.1+ 中,您也会看到错误:
type Three = [{}, {}, {}];
type Nine = [...Three, ...Three, ...Three];
type TwentySeven = [...Nine, ...Nine, ...Nine]
type UhOh = VariadicAndWithTransform<TwentySeven>; // error!
// -------> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Type instantiation is excessively deep and possibly infinite.
非递归版本对于人类来说更难理解,但它使编译器更容易:
type VariadicAndWithTransform<T extends any[]> = {
[K in keyof T]: (v: SimpleTransform<T[K]>) => void
}[number] extends ((v: infer I) => void) ? I : never
它的工作原理是 inferring in a conditional type来自逆变位置的联合(例如函数的参数),类似于 UnionToIntersection<T>从答案中输入 this question .
您可以验证它在上面的示例中的行为是否相同:
type Works = VariadicAndWithTransform<[{ a: 1 }, { b: 2 }, { c: 3 }]>;
/* type Works = SimpleTransform<{
a: 1;
}> & SimpleTransform<{
b: 2;
}> & SimpleTransform<{
c: 3;
}> */
并且因为它不使用递归,所以它在处理更长的元组时没有问题:
type StillWorks = VariadicAndWithTransform<TwentySeven>;
/* type StillWorks = { wrapped: {}; } */
Playground link to code

关于javascript - 在 typescript 中遍历可变元组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67409468/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com