Reputation: 9796
I want to create a type with a condition based on never
but I the results are unexpected (Typescript version 4.1.3).
type TypeCond<T, U> = T extends never ? {a: U} : {b: U};
let test: TypeCond<never, number>;
I have the TypeCond
that has a simple condition if T
extends never
.
I would expect that the type of the test
variable will be {a: number}
but actually, the type is never
.
I'm not sure why... If I replace the never
with undefined
or null
it works as expected. But I need the condition for the never
type.
Any idea why test
gets a never
type instead of {a: number}
?
Upvotes: 12
Views: 5968
Reputation: 51162
I believe this is a consequence of the distributive property of conditional types in Typescript. Essentially, (S | T) extends A ? B : C
is equivalent to (S extends A ? B : C) | (T extends A ? B : C)
, i.e. the conditional type distributes over the union in the extends
clause. Since every type T
is equivalent to T | never
, it follows that
T extends A ? B : C
is equivalent to (T | never) extends A ? B : C
,(T extends A ? B : C) | (never extends A ? B : C)
,never extends A ? B : C
.So a conditional type of the form never extends A ? B : C
must evaluate to never
, otherwise the distributive property would be violated.
To make your type work as intended, you can use this trick:
type TypeCond<T, U> = [T] extends [never] ? {a: U} : {b: U};
This avoids the conditional type distributing over T
, since [T]
is not a "naked type parameter".
Upvotes: 30