Introduction
In this chapter, we will explore the never
type in TypeScript. The never
type represents values that never occur. It is used to indicate that a function never returns, such as in the case of throwing an error or an infinite loop. Understanding how to use the never
type is essential for handling scenarios where a function cannot successfully complete.
Table of Contents
- Definition
- Using the
never
Type - Functions with
never
Return Type - Exhaustiveness Checking with
never
- Complete Example with Output
- Conclusion
Definition
The never
type in TypeScript represents values that never occur. It is used to indicate that a function never returns a value. This can happen if the function throws an error, enters an infinite loop, or otherwise never reaches a point where it returns.
Using the never Type
The never
type is primarily used for functions that never return a value. This includes functions that throw errors or run infinitely. The never
type can also be used in union types to perform exhaustive type checking.
Functions with never Return Type
When a function never successfully completes, you should specify the return type as never
. This makes it clear that the function does not produce a result under any circumstances.
Example
function throwError(message: string): never { throw new Error(message); } function infiniteLoop(): never { while (true) {} } throwError("An unexpected error occurred!"); // The following line will never be reached infiniteLoop();
Output
Error: An unexpected error occurred! at throwError (path/to/file.ts:2:9) ...
Exhaustiveness Checking with never
The never
type can be used to ensure that all possible cases are handled in a union type. This is useful for exhaustiveness checking in switch statements.
Example
type Shape = | { kind: "circle"; radius: number } | { kind: "square"; sideLength: number }; function getArea(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius ** 2; case "square": return shape.sideLength ** 2; default: // Exhaustiveness check const _exhaustiveCheck: never = shape; throw new Error(`Unhandled shape: ${_exhaustiveCheck}`); } } const circle = { kind: "circle", radius: 10 }; console.log(getArea(circle)); // Output: 314.159... const square = { kind: "square", sideLength: 5 }; console.log(getArea(square)); // Output: 25
Output
314.159... 25
Complete Example with Output
In this section, we will combine all the examples into a single TypeScript file, compile it to JavaScript, and run it to see the output.
TypeScript Code
You can test the following code in the TypeScript Playground:
// Functions with `never` Return Type function throwError(message: string): never { throw new Error(message); } function infiniteLoop(): never { while (true) {} } try { throwError("An unexpected error occurred!"); } catch (e) { console.error(e); } // The following line will never be reached // infiniteLoop(); // Exhaustiveness Checking with `never` type Shape = | { kind: "circle"; radius: number } | { kind: "square"; sideLength: number }; function getArea(shape: Shape): number { switch (shape.kind) { case "circle": return Math.PI * shape.radius ** 2; case "square": return shape.sideLength ** 2; default: // Exhaustiveness check const _exhaustiveCheck: never = shape; throw new Error(`Unhandled shape: ${_exhaustiveCheck}`); } } const circle = { kind: "circle", radius: 10 }; console.log(getArea(circle)); // Output: 314.159... const square = { kind: "square", sideLength: 5 }; console.log(getArea(square)); // Output: 25
Conclusion
In this chapter, we covered the never
type in TypeScript, including how to use it to indicate that a function never returns a value, and how to use it for exhaustiveness checking in union types. We provided a complete example with its output to illustrate how the never
type works in TypeScript. Understanding the never
type is essential for handling scenarios where a function cannot successfully complete.