Vla*_*pov 2 type-inference typescript
我不明白为什么Temptypenever在下面的情况下。我明白为什么它兼容,(...args: any) => infer R但如何never从中推断出类型?
// type ReturnType<T extends (...args: any) => any> = T extends (...args: any) => infer R ? R : any;
type Temp = ReturnType<never>;
Run Code Online (Sandbox Code Playgroud)
TL;DR 分配条件类型并且never是空联合
长版:
让我们先了解为什么ReturnType<never>幸福never有点起初令人吃惊:
从PR介绍never类型:
never 是每个类型的子类型并可分配给每个类型。
所以这意味着如果我们问这个问题never extend AnyOtherType呢?答案应该永远是肯定的。所以让我们问编译器这个问题:
type R = never extends (...args: any) => any ? "Y" : "N"; // Evaluates to "Y"
Run Code Online (Sandbox Code Playgroud)
因此,该定义确实成立并且never是(...args: any) => any. 但是为什么要ReturnType<never>解决never呢?如果推理失败,默认值通常unknown不是never( ref )。让我们在 之外尝试这个推论ReturnType:
type T0 = never extends (...args: any) => infer R ? R : any; //unknown
Run Code Online (Sandbox Code Playgroud)
因此,这是我们有一个非常惊人的结果,T0的确unknown,虽然ReturnType<never>是never甚至认为我们所做是内联的定义ReturnType在T0。
原因是分布条件类型。对裸类型参数具有条件的类型是分布式的。这意味着如果T是联合,则每个联合成分将通过条件类型独立运行,并将所有独立结果联合以获得最终结果。例如:
type T1 = ReturnType<(()=> number) | (() => string)> // number | string
Run Code Online (Sandbox Code Playgroud)
编译器如何评估上述类型:
ReturnType<(()=> number) | (() => string)>
-> ReturnType<()=> number> | ReturnType<() => string>
-> ((()=> number) extends (...args: any) => infer R) | ((()=> string) extends (...args: any) => infer R)
-> number | string
Run Code Online (Sandbox Code Playgroud)
好的,这与never. 那么never实际上是空联合 ( refernce ),一个没有成分的联合。这意味着当运行never分布条件类型时,条件类型实际上从不求值,因为在尝试分布时,没有什么可分布的。
我们可以ReturnType通过不留下T裸体来创建一个非分布式版本,并将其放在一个元组中,例如:
type ReturnTypeNonDistributive<T extends (...args: any) => any> = [T] extends [(...args: any) => infer R] ? R : any;
type Temp2 = ReturnTypeNonDistributive<never>; //unknown
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
105 次 |
| 最近记录: |