Typescript 类型脚本函数的交叉类型
我正在使用打字脚本,遇到了一些问题。最简单的演示是:Typescript 类型脚本函数的交叉类型,typescript,Typescript,我正在使用打字脚本,遇到了一些问题。最简单的演示是: type g = 1 & 2 // never type h = ((x: 1) => 0) & ((x: 2) => 0) // why h not never type i = ((x: 1 & 2) => 0)// why x not never 我不明白为什么typeh不是never,typeI中的paramx不是never type e = (((x: 1) => 0) &
type g = 1 & 2 // never
type h = ((x: 1) => 0) & ((x: 2) => 0) // why h not never
type i = ((x: 1 & 2) => 0)// why x not never
我不明白为什么typeh
不是never
,typeI
中的paramx
不是never
type e = (((x: 1) => 0) & ((x: 2) => 0)) extends (x: infer L) => 0 ? L : never; // why e is 2 not never or 1?
另外,我不明白为什么类型e
是2
而不是从不?以防万一
type h = ((x: 1) => 0) & ((x: 2) => 0)
将1
指定为x
的类型,也称为文字类型。文字类型位于从不
最小值集的旁边。never
和literal type1
之间的区别在于never
是一个空集合,但1
集合中只有一个值。因此,永远不会
!==<代码>1
这里
参数x
的类型为never
注:非原语类型通常用大写字母书写;这将它们与基元类型和变量/属性名称区分开来。我将在下文中使用此约定
type e = (((x: 1) => 0) & ((x: 2) => 0)) extends (x: infer L) => 0 ? L : never; // why e is 2 not never or 1?
这个问题有很多问题,所以答案也会有很多问题
让我们先解决容易的问题:
type G = 1 & 2 // never
将像1和2
这样的空交叉口减少到never
,是在中实现的,并使用TypeScript 3.6发布。在此之前,1&2
被视为非常类似于never
,因为您永远无法找到满足它的值。1&2
和never
之间实际上没有概念上的区别,尽管编译器实现细节可能会导致其中一个与另一个不同
下一个:
type I = ((x: 1 & 2) => 0) // why x not never
x
是never
,但在您实际使用它之前,将延迟减少:
type IParam = Parameters<I>[0]; // never
实际上,H
不是从不
的原因有很多:
- TypeScript特定的原因是,函数类型的交集被视为与具有多个调用签名的相同:
declare const h: H;
// 1/2 h(x: 1): 0
// 2/2 h(x: 2): 0
h(1); // okay
h(2); // okay
h(3); // error, no overload matches this call
h(Math.random() < 0.5 ? 1 : 2); // error, no overload matches this call
回想一下前面提到的函数的交集被认为是重载函数。TypeScript的一个已知设计限制是,当对重载函数类型使用类型推理时,编译器不会试图通过找出哪个调用签名与预期推理最匹配来解决重载问题。它只使用最后一个调用签名,而忽略所有其余的调用签名。在E
中,这意味着编译器在与(x:inferl)=>0
进行匹配时只看到(x:2)=>0
,因此L
被推断为2
。“正确”的做法可能是工会1 | 2
,但这不会发生。请参阅此限制的一个实例
很好的解释!你可以自由回答另一个问题吗?我也被困住了。我现在没有时间去经历所有这些;我可能晚点再看
declare const h: H;
// 1/2 h(x: 1): 0
// 2/2 h(x: 2): 0
h(1); // okay
h(2); // okay
h(3); // error, no overload matches this call
h(Math.random() < 0.5 ? 1 : 2); // error, no overload matches this call
type E = (((x: 1) => 0) & ((x: 2) => 0)) extends (x: infer L) => 0 ? L : never;
// why E is 2 not never or 1?