当不可能的交叉点产生“never”类型时,行为不一致

Joj*_*oji 8 typescript

我发现never当不可能的交叉点发生时,TypeScript 会在不同级别生成类型

\n
\ntype Foo = {name: string, age: string}\ntype Bar = {name: string, age: number}\n\ntype Baz = Foo & Bar\nconst baz: Baz = {name: '123,', age:13} // \xe2\x9d\x8c Type 'number' is not assignable to type 'never'.\n\n
Run Code Online (Sandbox Code Playgroud)\n

上面的例子导致类型Baz{name: string, age:never}

\n

但是如果我们稍微改变一下Bar

\n
type Foo = {name: string, age: string}\ntype Bar = {name: string, age: boolean}\n\ntype Baz = Foo & Bar // the whole `Baz` type is `never`\n
Run Code Online (Sandbox Code Playgroud)\n

现在整个Baz类型是never. 我不明白为什么 TypeScript 这样做。有人可以帮助我理解这一点吗?

\n

jca*_*alz 2

在 TypeScript 3.9 之前,两个交集的行为都类似于您的第一个示例,并且相当于{name: string, age: never}. TypeScript 3.9 引入了通过判别属性减少交叉点的功能。判别属性大致是那些其值是单一文字类型(如字符串文字类型、数字文字类型、布尔文字类型、nullundefined)或此类类型的联合的属性。这些用于受歧视的工会。如果交集类型导致判别式属性减少为never,则编译器会将整个交集减少为never。有关详细信息和动机,请参阅microsoft/TypeScript#36696 。

不管怎样,类型boolean被表示为联合true| false布尔文字,因此age第二个示例中的属性被认为是判别属性。另一方面,number是非文字类型,因此age第一个示例中的属性不被视为判别属性。这解释了您所看到的行为差异。