Observing TypeScript Never With Conditional With Parameter
I was surprised by something in TypeScript today regarding the combination of:
- Type Conditional
- Type Parameter
- Never Type
Here are some basic sub/super type tests with never:
type is_1_extends_never = 1 extends never ? true : false
// false
type is_never_extends_1 = never extends 1 ? true : false
// false
type is_never_extends_never = never extends never ? true : false
// true
No surprise (to me).
But something happens when a type parameter is introduced which I did not expect.
namespace check_is_never_extends_parameter {
type $<p> = never extends p ? true : false
type is_never_extends = $<1> // never extends 1 ? true : false
// true
type is_never_extends_never = $<never> // never extends never ? true : false
// true
}
namespace check_is_parameter_extends_never {
type $<p> = p extends never ? true : false
type is_never_extends_never = $<never> // never extends never ? true : false
// never <------------------------------------------------------------------ ???
type is_1_extends_never = $<1> // 1 extends never ? true : false
// false
}
namespace check_is_1_extends_parameter {
type $<p> = 1 extends p ? true : false
type is_1_extends_never = $<never> // 1 extends never ? true : false
// false
type is_1_extends_1 = $<1> // 1 extends 1 ? true : false
// true
}
namespace check_is_parameter_extends_1 {
type $<p> = p extends 1 ? true : false
type is_1_extends_never = $<never> // 1 extends never ? true : false
// never <---------------------------------------------------------- ???
type is_1_extends_1 = $<1> // 1 extends 1 ? true : false
// true
}
The difference is that:
never
given as a type argument- … to a conditional type
- … where the respective parameter is referenced in the sub-type-position of the conditional (
x (<-- sub-type position) extends y (<-- super-type position)
) - … evaluates to
never
- … instead of the conditional being evaluated (in this case,
true
/false
).
I find this behavior counterintuitive.
Perhaps there is a good reason for it, but to me right now it feels like a bug.
I am using TypeScript version 5.8.3
.
Here is a TypeScript Playground.
I filed a bug issue with TypeScript fwiw (I suspect I’ll be given an explanatioin why this is not a bug).