In TypeScript, the never
type signifies a type that never returns a value. Just like the question has pointed out, it's indeed correct to denote the never
type as a type that never returns any value.
function throwError(message: string): never {
throw new Error(message);
}
In the example above, the function throwError
throws an error and does not return anything. Hence the return type of throwError
is never
.
The never
type is a subtype of all types; however, no type is a subtype of never
(excluding never
itself). This makes it a valuable tool for ensuring exhaustive type-checking in your TypeScript programs.
In contrast to void
, which represents lack of return value, never
is used when a function does not have a reachable endpoint. For instance, a function that always throws an error will never reach its end point. In such a scenario, the function's return type can be annotated as never
.
One practical use of the never
type is to enforce exhaustive checking, especially useful in a switch case.
type Foo = {
type: 'a';
a: number;
} | {
type: 'b';
b: string;
};
function doStuff(foo: Foo) {
switch (foo.type){
case 'a':
return foo.a;
case 'b':
return foo.b;
default:
const check: never = foo;
return check;
}
}
In the code snippet above, if there's a case unaccounted for, TypeScript will flag off a compile-time error.
It's crucial not to confuse never
with void
or undefined
in TypeScript. never
represents a value that's never observed, for instance, when a function always throws an exception or never returns because it runs an infinite loop.
A good principle to follow would be to use never
when you want to indicate that something should not happen or if you are dealing with functions that explicitly do not return any value. By doing so, you'll adhere to best coding practices, ensuring that your TypeScript code is both precise and exhaustive in its type-checking process.