The TypeScript never
keyword is a bit of a mystery to many developers. What does it do, and when should you use it? Today we will discuss the never
keyword in-depth, and cover the situations where you could encounter it.
Characteristics of “never”
TypeScript uses the never
keyword to represent situations and control flows that should not logically happen.
In reality, you won’t come across the need to use never
in your work very often, but it’s still good to learn how it contributes to type safety in TypeScript.
Let’s see how the documentation describes it: "The never type is a subtype of, and assignable to, every type; however, no type is a subtype of, or assignable to, never (except never itself)."
TLDR; of the above is that you can assign a variable of the type never
to any other variable, but you cannot assign other variables to never
. Let’s take a look at a code sample:
|
|
You can ignore throwErrorFunc
for now. Just know that’s a workaround for initializing a variable with type never.
As you can see from the above code, we can assign our variable neverVar
of type never
to a variable myInt
which is of type number
. However, we cannot assign the myString
variable of type string
to neverVar
. That will result in a TypeScript error.
You can’t assign variables of any other type to never
, even variables of type any
.
“never” in functions
TypeScript uses never
as a return type for functions that will not reach their return endpoint.
This could mainly happen for two reasons:
- The function throws an error exception.
- The function contains an infinite loop.
You've already seen `throwErrorFunc` in our previous code. This is an example of a function that throws an exception:
|
|
Another case is if you have an infinite loop with a truthy expression that doesn’t have any breaks or return statements:
|
|
In both cases, TypeScript will infer that the return type of these functions is never
.
Difference between “never” and “void”
So what about the void
type? Why do we even need never
if we have void
?
The main difference between never and void is that the void
type can have undefined
or null
as a value.
TypeScript uses void
for functions that do not return anything. When you don’t specify a return type for your function, and it doesn’t return anything in any of the code paths, TypeScript will infer that its return type is void
.
In TypeScript, void
functions that don’t return anything are actually returning undefined
.
|
|
However, we usually ignore the return values of the void
functions.
Another thing to note here: as per the characteristics of the never
type we covered earlier, you cannot assign void to never:
|
|
“never” as the variable guard
Variables can become of the type never
if they are narrowed by a type guard that can never be true. Usually, this indicates a flaw in your conditional logic.
Let’s take a look at an example:
|
|
In the above example, when the function execution reaches the line console.log({ myParam })
, the type of myParam
will be never
.
This happens because we’re setting the type of myParam
to be either “this” or “that”. Since TypeScript assumes that those two are the only possible choices in this situation, logically, the third else statement should never occur. So TypeScript sets the parameter type to never
.
Exhaustive Checks
One of the places you might see never
in practice is in exhaustive checks. Exhaustive checks are useful for ensuring that you’ve handled every edge case in your code.
Let’s take a look at how we can add a better type safety to a switch statement using an exhaustive check:
|
|
When you add return shouldNotHappen(pet)
, you should immediately see an error:
The error message informs you of the case you forgot to include in your switch statement. It's a clever pattern for getting compile-time safety and ensuring you handled all the cases in your switch statement.
Conclusion
As you can see, the never
type is useful for specific things. Most of the time, it’s an indication that there are flaws in your code.
But in some situations, such as exhaustive checks, it can be a great tool to help you write safer TypeScript code.
If you’d like to get more web development, React and TypeScript tips consider
following me on Twitter,
where I share things as I learn them.
Happy coding!