How to Use of the never Keyword in TypeScript

TypeScript is a powerful superset of JavaScript that introduces static typing to help developers catch errors early. One of the most intriguing types in TypeScript is the never
keyword.
In this tutorial, we will explore the never
type in detail, providing you with a comprehensive understanding of its purpose and use cases. From defining functions that never return to handling exhaustive checks in union types, we will cover practical examples and scenarios where the never
type shines. By the end of this guide, you will have a clear grasp of how to effectively utilize the never
keyword in your TypeScript projects.
What is the never Keyword?
The never
type is a unique type in TypeScript that indicates values that will never occur. This can be particularly useful in several scenarios, such as when dealing with functions that throw errors or when implementing exhaustive type checks. When a function is defined to return never
, it signifies that the function will not return a value, either because it throws an exception or because it enters an infinite loop.
For instance, consider a function that always throws an error. Since this function will never return a value, it can be typed as returning never
. This type helps TypeScript understand the flow of your code better, allowing for more accurate type checking and error reporting.
Here’s a simple example of a function that uses the never
type:
function throwError(message: string): never {
throw new Error(message);
}
In this example, the throwError
function takes a string message as an argument and throws an error. Since it never completes normally, its return type is never
.
Output:
This function will throw an error and never return a value.
The never
type is also beneficial when working with union types, particularly when you want to ensure that all possible cases are handled. By using never
, you can enforce exhaustive checks in your type guards.
Using never with Union Types
When working with union types in TypeScript, the never
type can help ensure that all potential cases are accounted for. This is particularly important in scenarios where you have a finite set of options. By using never
in your type checks, you can catch errors early in the development process.
Consider the following example where we define a union type for different shapes and a function that calculates their area:
type Shape = 'circle' | 'square' | 'rectangle';
function calculateArea(shape: Shape, size: number): number {
switch (shape) {
case 'circle':
return Math.PI * size * size;
case 'square':
return size * size;
case 'rectangle':
return size * size * 2; // Example for width and height being the same
default:
const _exhaustiveCheck: never = shape;
return _exhaustiveCheck; // This line will throw a compile error if not handled
}
}
In this code snippet, we define a Shape
type that can be either a circle, square, or rectangle. The calculateArea
function uses a switch statement to handle each shape. The default case is where the never
type comes into play. By creating a variable _exhaustiveCheck
of type never
, we ensure that if any shape outside of the defined union is passed, TypeScript will throw a compile-time error.
Output:
The function will throw an error if an unrecognized shape is passed.
This use of never
ensures that our code is robust and that we handle all possible cases. It also serves as a reminder to developers that they need to consider all potential values of the union type.
Handling Errors with never
Another common use case for the never
type is in error handling. When you have a function that is designed to throw an error, you can specify its return type as never
. This clearly communicates to other developers that the function will not return a value in the normal flow of execution.
Here’s an example of how you might implement this:
function assertIsDefined<T>(value: T | undefined, message: string): T {
if (value === undefined) {
throw new Error(message);
}
return value;
}
In this function, assertIsDefined
, we check if a value is undefined
. If it is, we throw an error with a specified message. The return type of this function is T
, but if the value is undefined
, it will throw an error and never return normally.
Output:
The function will throw an error if the value is undefined.
Using the never
type in this context helps to enforce type safety, ensuring that the function’s contract is clear. It indicates that if you pass an undefined value, you will not get a valid return.
Conclusion
The never
keyword in TypeScript is a powerful tool for developers, enabling them to write more robust and error-free code. By understanding its purpose and how to use it effectively, you can improve the type safety of your applications. Whether you’re handling errors, working with union types, or defining functions that throw exceptions, the never
type provides clarity and confidence in your code. As you continue to explore TypeScript, keep the never
keyword in mind as a means to enhance your type definitions and error handling strategies.
FAQ
-
What does the never keyword indicate in TypeScript?
The never keyword indicates values that will never occur, such as functions that throw errors or enter infinite loops. -
How can I use never with union types?
You can use never to enforce exhaustive checks in union types, ensuring that all possible cases are handled in your code. -
Can a function with a return type of never return a value?
No, a function with a return type of never cannot return a value; it will either throw an error or enter an infinite loop. -
Why is the never type useful?
The never type is useful for catching errors at compile time, improving type safety, and ensuring that all cases in switch statements or type guards are accounted for. -
How do I handle errors using the never type?
You can define functions that throw errors with a return type of never to indicate that they will not return a value in the normal flow of execution.
Ibrahim is a Full Stack developer working as a Software Engineer in a reputable international organization. He has work experience in technologies stack like MERN and Spring Boot. He is an enthusiastic JavaScript lover who loves to provide and share research-based solutions to problems. He loves problem-solving and loves to write solutions of those problems with implemented solutions.
LinkedIn