Reputation: 198328
There is type definition in typescript:
type Exclude<T, U> = T extends U ? never : T;
We can use it to exclude a type from another type:
type AB = 'a' | 'b'
type AC = 'a' | 'c'
type X = Exclude<AB, AC>
The type X
is b
now.
But when I use the content of Exclude
directly:
type X = AB extends AC ? never : AC;
The type X
is different, it's not b
anymore, it's AC
.
I can't understand why it behaves differently.
Upvotes: 4
Views: 152
Reputation: 250136
Firstly if you replace the content, X
would be type X = AB extends AC ? never : AB;
. But that will not give you the same result either.
The reason is that conditional types have a special behavior when it comes to naked type parameters, they distribute over them if they are a union. So when you use Exclude
, each member of the union is separately put through the condition and the result is unioned. So Exclude<AC, AB>
is equivalent to:
type X = ('a' extends AC ? never : 'a') | ('b' extends AC ? never : 'b')
This distributive behavior does not occur with anything except naked type parameters (naked meaning T
is not used in another type, such as a tuple, an array or as a parameter to another generic type), this is why using the type directly in the condition does not yield the same result. You can read more here
Upvotes: 7