无法正确理解打字稿中的`Exclude <T,U>`

Fre*_*ind 2 types typescript

打字稿中有类型定义:

type Exclude<T, U> = T extends U ? never : T;
Run Code Online (Sandbox Code Playgroud)

我们可以使用它从另一个类型中排除一个类型:

type AB = 'a' | 'b'
type AC = 'a' | 'c'

type X = Exclude<AB, AC> 
Run Code Online (Sandbox Code Playgroud)

现在X是类型b

但是当我Exclude直接使用以下内容时:

type X = AB extends AC ? never : AC;
Run Code Online (Sandbox Code Playgroud)

类型X不同,现在b不再是AC

我不明白为什么它的行为有所不同。

Tit*_*mir 5

首先,如果你更换内容,X将是type X = AB extends AC ? never : AB;。但这也不会给您相同的结果。

原因是在涉及裸类型参数时,条件类型具有特殊的行为,如果它们是一个并集,则它们将分布在它们之上。因此,当您使用时Exclude,并集的每个成员都单独经过该条件,结果将被并集。因此Exclude<AC, AB>等于:

type X = ('a' extends AC ? 'a' : never) | ('b' extends AC ? 'b' : never)
Run Code Online (Sandbox Code Playgroud)

除裸类型参数外,其他任何情况都不会发生这种分配行为(裸含义T不用于其他类型,例如元组,数组或作为其他泛型类型的参数),这就是为什么直接在条件中使用类型的原因无法产生相同的结果。你可以在这里阅读更多