cbd*_*per 3 typescript typescript-typings union-types typescript-types
我在试图绕过这样一个事实时遇到了一些麻烦,即类型never
毫无意义并且可以在它位于union type内时被丢弃。
我的意思是,我在一个交集类型中得到它,never
将立即使所有结果都变成never
,因为没有任何类型可以通过某种类型和never
相同的类型。对于我,这说得通。
但是在联合类型中,我的直觉最初告诉我该never
类型将是一个有效的选项。我的问题是为什么不是?为什么never
可以在联合类型中丢弃?
有人可以对此做出合理的解释,以便我更好地理解它吗?
一种将类型视为可分配给它的所有值的集合。因此boolean
可以将其视为 { true
, false
} ,即仅包含这两个值的集合。并且string
可以被认为是包含每个可能string
值的(本质上)无限集。
在 TypeScript 中,never
是底部类型。它没有任何价值。如果你有一个 JavaScript 值并且你问“这是一个类型的值never
吗?” 那么答案是“不”。就集合而言,never
可以认为是 ?,
空集。
在从类型到值集的映射中,TypeScript 中的交集操作(&
)可以被认为是集交集操作(?)。如果你有集合A和B,则A-B是一组恰好它们的成员的对象的两个甲和B.对任意集合A,所述交点A?空集只是空集?。A 和空集中都没有元素,因为空集中根本没有元素。回到 TypeScript 类型,这意味着A & never
变为never
任何类型A
。如果 TypeScript 编译器只是保留string & never
为string & never
,那将是有效的,但实际上它会继续并将其减少为never
自动,因为后一种表示更简单。
另一方面:在从类型到值集的映射中,TypeScript ( ) 中的联合操作|
可以被认为是集合联合操作 (?)。如果您有集A和B,那么A?B是集到底哪个是成员对象的任何一个或B(这是一个包容性的或)。对于任何集合 A,联合 A?? 空集就是A。联合包含A的所有元素和空集的所有元素。由于没有空集的元素,这只是“A 的所有元素”。回到 TypeScript 类型,这意味着A | never
变为A
任何类型A
。如果 TypeScript 编译器只是保留string | never
为string | never
,但实际上它会继续并string
自动将其减少,因为后一种表示更简单。
所以这就是基本的解释。还有其他类比,例如布尔逻辑命题,例如“此元素是此类型的成员”,对于该never
类型始终为 FALSE ,导致诸如 A ? FALSE = FALSE 和 A ? FALSE = A. 或者像算术一样,类比不精确,但交集看起来像乘法,并集看起来像加法(这个类比对于对而不是交集和有区别的联合而不是常规联合变得精确)并且never
类型是 0。但希望这能提供足够的直觉来了解编译器为什么会这样。
请注意,也有一个顶级型的打字稿叫unknown
这正好表现为双到never
在A & unknown = A
和A | unknown = unknown
,并在集理论的双模拟(该全集/班)。但是你没有问这个问题,这个答案已经足够长了。