我有两个文字类型,我想从联合 A 中排除 B。
type A = 'a' | 'b'
type B = 'a'
当我这样做时:
type MyExclude<A2, B2> = A2 extends B2 ? never : A2
type C2 = MyExclude<A, B>
// C2 = 'b'
它工作正常,即我得到“b”。
但是当我这样直接做的时候:
type C = A extends B ? never : A
// C = 'a' | 'b'
事实并非如此。为什么我是通过中间泛型类型还是直接这样做很重要?
谢谢。
最佳答案
当您将其作为泛型执行时,Typescript 会将检查分布地应用于联合体的每个成员。所以type C2 = MyExclude<A, B>
将不会被评估为 'a | b' extends 'a' ? never : 'a | 'b'
,而是 ('a' extends 'a' ? never : 'a') | ('b' extends 'a' ? never : 'b')
. 'a' 确实扩展了 B,因此结果为 never
. 'b' 不扩展 B,因此结果为 'b'。最后的结果是never | 'b'
, 这就是 'b'
.
如果不是泛型,则分配部分不会发生。 type C = A extends B ? never : A
将被评估一次,如'a | b' extends 'a' ? never : 'a | 'b'
. 'a' | 'b'
不扩展 'a'
,所以结果是整个类型,'a' | 'b'
参见 distributive conditional types
Distributive conditional types
Conditional types in which the checked type is a naked type parameter are called distributive conditional types. Distributive conditional types are automatically distributed over union types during instantiation. For example, an instantiation of
T extends U ? X : Y
with the type argumentA | B | C
forT
is resolved as(A extends U ? X : Y) | (B extends U ? X : Y) | (C extends U ? X : Y)
.
关于 typescript 文字联合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/73744524/