Never in a function
What the never type means
The never type denotes:
"This function will never complete successfully and will never return anything."
In other words, there is no path in the code where the function could return a value. It either:
- throws an exception (
throw), - or runs an infinite loop (
while (true)), - or its completion is simply logically impossible.
Example 1. A function that throws an error
function throwError(message: string): never {
throw new Error(message);
}- The function does not return a value, it throws an exception.
- After
throw, execution never continues.
The
nevertype shows that the code "interrupts execution" forever.
Example 2. A function with an infinite loop
function infiniteLoop(): never {
while (true) {
console.log("Running forever...");
}
}- The loop never ends, so there is no point where a value could be returned.
- TypeScript understands that the function can never complete, and assigns it the
nevertype.
Example 3. An impossible code branch (exhaustiveness check)
This is the most common and most useful application of never,
for checking that we have handled all possible cases in a switch or if.
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number };
function getArea(shape: Shape): number {
switch (shape.kind) {
case "circle":
return Math.PI * shape.radius ** 2;
case "square":
return shape.side ** 2;
default:
// this branch is unreachable!
const _exhaustiveCheck: never = shape;
throw new Error(`Unknown shape: ${_exhaustiveCheck}`);
}
}If later you add a new type, for example:
type Shape =
| { kind: "circle"; radius: number }
| { kind: "square"; side: number }
| { kind: "triangle"; base: number; height: number };TypeScript will raise an error:
Type
'triangle'is not assignable to typenever.
That means you need to add a new case "triangle": branch.
This way, never helps you control the exhaustiveness of the logic.
Example 4. never in callbacks and generics
Sometimes never appears automatically,
when TypeScript cannot infer a possible type (for example, in an empty array):
const arr: never[] = []; // an array that can never hold valuesor in functions with a narrow type:
function fail(): never {
throw new Error("Error");
}
function process<T>(value: T): T {
if (typeof value === "string") {
return value.toUpperCase() as T;
}
fail(); // returns never, so TypeScript knows the code below never runs
}Key features of never
| Property | Description |
|---|---|
| Semantics | The function never returns a value |
| Occurs with | throw, while(true), "impossible" branches |
| Subtype of all types | never can be assigned to anything (string, number, void, etc.) |
But no type can be assigned to never | except never itself |
| Common use | Checking exhaustive conditions (exhaustive check) |
Comparison of never with other types
| Type | Description | Example |
|---|---|---|
void | The function completes but returns nothing | function log(): void { console.log("ok"); } |
undefined | The function returns undefined | function f(): undefined { return undefined; } |
never | The function never completes | function loop(): never { while(true){} } |
The simple way to remember it
The
voidtype: the function completed, but did not return a value.The
nevertype: the function did not complete at all (an error, an infinite loop, unreachable code).
Final example
function doSomething(action: "run" | "stop" | "pause") {
switch (action) {
case "run":
console.log("Running");
break;
case "stop":
console.log("Stopping");
break;
case "pause":
console.log("Pausing");
break;
default:
const impossible: never = action; // exhaustiveness check
throw new Error(`Unexpected action: ${impossible}`);
}
}If you forget one
case, TypeScript will force you to add it.
Short Answer
Interview readyA concise answer to help you respond confidently on this topic during an interview.