All Things Typescript

Share this post

When is a variables' Type Never?

www.allthingstypescript.dev

Discover more from All Things Typescript

Learn and develop an innate understanding of Typescript and its typing system with weekly lessons and get the most out of Typescript.
Continue reading
Sign in

When is a variables' Type Never?

Demystifying the Typescript never Type by looking at situations where you may encounter the never Type in your day-to-day activities.

Maina Wycliffe
Jun 19, 2023
2
Share this post

When is a variables' Type Never?

www.allthingstypescript.dev
Share

Have you come across the never type before? If not, let me tell you more about this in this issue of All Things Typescript. In this issue, I want to explore situations in which a variable can have the never Type.

But before we do that, what’s the never Type? To understand this, let’s explore Types first. Types, in Typescript and in language for that matter represent a series of possible values, for instance, for a variable whose type is a number, the possible values for the variable are any number in the planet, from zero to infinity (or negative infinity).

The same applies to a variable whose type is a string, it could be anything from a single character in the alphabet to a whole blog post or the bible. When it comes to the any type, this encompasses all values, be it numbers, strings, boolean, arrays, boolean, and any type (pun intended) of value that can exist - which is why I discourage you from using the any type - we will explore this in a future issue of All Things Typescript.

Subscribe and learn Typescript with Weekly Lessons

When it comes to the never type, it’s the opposite of the any type, it represents the absence of possible values. It means that a variable, whose type is never, can not exist (its values don’t exist).

So, I know what you are thinking right about now, when is a variable Type never? Let’s have a look at a couple of scenarios:

Control Flow Narrowing

The control flow is the order in which the computer executes statements in a script. - MDN Docs

If you narrow your variable, there is a possibility that you will end up with a situation where the final else is going to result in the never type. Take the following function, which accepts an input of either number or string - assume it does something interesting.

function doSomething(input: number | string) {
 // body
}

If we narrowed our input, by exhaustively checking every possible scenario, so that we can do something different based on the variable type, we can do it something like this:

if(typeof input === "string") {
    // do something with string
} else if (typeof input === "number") {
    // do something with number
} else {
    // NEVER
    console.log(input);
}

In the first, if condition, we are narrowing to the string type when the condition is true. And in the second, condition, we are narrowing to the number type when the condition is true, But in the last condition, since our variable can only be either number or string, then it can’t possibly have a value, hence the never type is inferred, as shown below.

Control Flow Type Narrowing can result in the never type in Typescript

The inferred return type of function expressions with unreachable Endpoint

In Javascript, and obviously by extension, in Typescript, we have multiple ways of declaring functions, we have the function declaration, the most common one by far, then the arrow function expression, and then the function expression. In this section, we are talking about the latter two.

When using either a function expression or the more compact arrow syntax to define a function and the function never returns a value, for instance, throws an error or an infinite loop, then typescript will automatically infer the never type.

Let’s see an example:

const doSomething = (message: string) => {
    throw new Error(message)
}

In the first example above, our arrow function expression, throws an error, meaning it never returns, and hence, it automatically infers the never type as its return type.

The inferred type of a function expression with an unreachable endpoint is never

This behavior can be seen when using the less compact function expression, as shown below:

const doSomething = function(message: string) {
  throw new Error(message)
}
The inferred type of a function expression with an unreachable endpoint is never

Explicit Annotation of the never Type

Another way you can have a never type is either explicitly annotating the variable to never or assigning to a variable another variable that’s never. I don’t have a good reason as to why anyone would want to do that, so if you do, feel free to drop a comment in the section below.

On top variables, functions can be annotated to return the never type. This kind of function must have an unreachable endpoint, for instance, an infinite loop, as shown below.

function doSomething(): never {
    while(true) {
        // infinite loop
    }
}

Another example of such a function throws an error:

function doSomething(): never {
    throw Error("Error Message")
}

In either of the case above, if you returned either of the above functions or assigned them to a variable, the inferred type is going to be never.

Please do not use x as your variable name 😁, make it meaningful

There are a few more things to understand when it comes to the never type:

For instance, A variable whose type is never can only be assigned a never value, in this case, another variable of type never and nothing else, including the any type. If you tried, you will get an error similar to the following:

Type 'string' is not assignable to type 'never'

The same applies to functions, whose return type is explicitly annotated as never, can only return never or have an unreachable endpoint, as previously discussed. If you return some other type, Typescript is going to be screaming at you, as shown below:

Type 'string' is not assignable to type 'never'

Conclusion

In this issue of All Things Typescript, we demystified the Typescript never Type and looked at situations where you may encounter the Type. In most cases, when you encounter the never type, it signals there could be something wrong with your code that results in Typescript inferring the never type.

That’s it for this week and If you enjoyed reading this article, please like, share, and subscribe to learn Typescript every week.

Share

Thank you ❤️.


Previous Issues

Looking up the Input and Output Types of a Function using the Parameters & ReturnType Utility Types

Looking up the Input and Output Types of a Function using the Parameters & ReturnType Utility Types

Maina Wycliffe
·
Jun 5
Read full story
Using Zod Schemas as Source of Truth for Typescript Types

Using Zod Schemas as Source of Truth for Typescript Types

Maina Wycliffe
·
Jan 23
Read full story
How to Overload Functions in Typescript

How to Overload Functions in Typescript

Maina Wycliffe
·
September 12, 2022
Read full story
2
Share this post

When is a variables' Type Never?

www.allthingstypescript.dev
Share
Previous
Next
Comments
Top
New
Community

No posts

Ready for more?

© 2023 Maina Wycliffe
Privacy ∙ Terms ∙ Collection notice
Start WritingGet the app
Substack is the home for great writing