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
我不明白为什么type
h
不是
never
,type
I
中的param
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?
另外,我不明白为什么类型
e
2
而不是
从不

以防万一

type h = ((x: 1) => 0) & ((x: 2) => 0)
1
指定为
x
的类型,也称为文字类型。文字类型位于
从不
最小值集的旁边。
never
和literal type
1
之间的区别在于
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?