请考虑以下几点:
export type UwrapNested<T> = T extends Iterable<infer X> ? UwrapNested<X> : T
我得到了类型错误(使用TypeScript 3.9.4):类型'UwrapNested‘不是泛型的
这是由于类型系统的某些限制吗?
发布于 2020-06-28 18:02:25
是的,条件类型不能以这种方式直接递归。见微软/打字稿#26980。人们用了很多技巧来规避这个问题。我推荐的唯一一种方法是将您的类型循环展开为一系列几乎相同的类型,这些类型在某个固定的深度处跳出,如下所示:
type UnwrapNested<T> = T extends Iterable<infer X> ? UN0<X> : T;
type UN0<T> = T extends Iterable<infer X> ? UN1<X> : T;
type UN1<T> = T extends Iterable<infer X> ? UN2<X> : T;
type UN2<T> = T extends Iterable<infer X> ? UN3<X> : T;
type UN3<T> = T extends Iterable<infer X> ? UN4<X> : T;
// ...
type UN4<T> = T extends Iterable<infer X> ? UNX<X> : T;
type UNX<T> = T; // bail out您根据编译器的性能和预期的用例选择“退出”深度。是的,它很丑,但很简单,而且是“合法的”:
type UOkay = UnwrapNested<string[][][][]> // string
type UTooMuch = UnwrapNested<string[][][][][][][][]> // string[][]还有其他一些技巧提到,使用分布条件类型延迟评估,并欺骗编译器认为类型不是递归的,但这些是脆弱的,有非常奇怪的副作用,不一定支持。例如
type UnwrapNestedIllegal<T> = {
base: T, recurse: UnwrapNestedIllegal<T extends Iterable<infer X> ? X : never>
}[T extends Iterable<any> ? "recurse" : "base"]在尝试使用它之前,这看上去是不太可能的,然后得到一个循环错误:
type Oops = UnwrapNestedIllegal<string> // any有什么方法可以改变UnwrapNestedIllegal来解决这个问题吗?可能吧。是个好主意吗?我说“不”,虽然我可能有对这一问题的极端看法。事实上,我绝对希望有一种官方支持的方法来获得递归条件类型,但是如果没有语言设计人员的强烈承诺,我就不能凭良心推荐任何人使用这些技巧。
好吧,希望这能帮上忙,祝你好运!
发布于 2020-06-28 19:18:41
正如@jcalz所证实的,我就是这样解决这个问题的:
type UnwrapIterable1<T> = T extends Iterable<infer X> ? X : T
type UnwrapIterable2<T> = T extends Iterable<infer X> ? UnwrapIterable1<X> : T
type UnwrapIterable3<T> = T extends Iterable<infer X> ? UnwrapIterable2<X> : T
export type UnwrapNestedIterable<T> = T extends Iterable<infer X> ? UnwrapIterable3<X> : Thttps://stackoverflow.com/questions/62621963
复制相似问题