Typescript Never Type
By Henri Parviainen
Typescript has a type called never
. Have you never heard of it?
No worries.
In this post, we will explain the never
type in detail, so after you are done reading this post, you'll know exactly what Typescript never
type is and what it is used for.
According to the Typescript docs, the never
type represents the type of values that never occur.
The
never
type is a subtype of, and assignable to, every type; however, no type is a subtype of, or assignable to,never
(exceptnever
itself). Evenany
isn’t assignable tonever
.
Typescript never type examples
Using never
in a function that throws an error
Most commonly, you'll see the never
type in a function that only throws an error.
Let's look at some code.
const generateError = (message: string, code: number) : never => {
throw new Error(message: message, errorCode: code)
}
Here we have a function that generates an error based on the message and code that it receives as a parameter. What makes this function special is that it actually never returns anything. It only throws an error.
never
in a function including infinity loop
Another example of a function that has a type never
would be a function that has an infinite while loop that never returns.
const infinity = (): never => {
while (true) {
console.log("I will never return.");
}
};
Where to use the never
type?
One benefit of using the never
type is to make your intent clear for other developers. You can explicitly set a function type to never
if your intention is that the function will never return anything. This can help to make your code more readable for other developers.
Alternatively, you would use void
but that is not as clear about your intent.
Another use case for never
would be to use it to make sure all intended options are handled in some specific switch case function.
Let me explain what I mean in a bit more detail.
Only something that is of type never
can be assigned to a variable that has been declared as type never
.
We can take advantage of this information and use it to make sure we handle everything we need in a function.
type A = 1 | 2;
declare const a: A;
const exhaustiveCheck = (input: never) => {
throw new Error();
};
switch (a) {
case 1:
break;
case 2:
break;
default:
exhaustiveCheck(a);
}
In the above code, we use exhaustiveCheck
function to make sure we have handled all cases we intended to.
Remember that never
represents the type of values that never occur.
Now, if we have handled all possible cases, then the default case would never run and thus a
is of type never
.
If we would have forget to handle some case we would get an error.
type A = 1 | 2;
declare const a: A;
const exhaustiveCheck = (input: never) => {
throw new Error();
};
switch (a) {
case 1:
break;
// If we forget to handle case 2 here, we get an error
default:
exhaustiveCheck(a);
}
// Argument of type 'number' is not assignable to parameter of type 'never'.
So there you have it.
That is Typescript never
type in a nutshell.