Note: If you're new to TypeScript, check our Getting Started with TypeScript tutorial first.
In TypeScript, the never
type represents values that never occur. It is often used to denote functions that never return a value, typically because they throw an exception.
Here's a simple example of the never
type. You can read the rest of the tutorial to learn more.
Example
function crash(): never {
throw new Error("Something went wrong!");
}
crash();
Here, crash()
is a function that returns a value of type never
. This means crash()
never finishes normally and can't return a value — not even undefined
.
TypeScript never Type With Function
Suppose you have a function named showFatalError()
with type never
.
function showFatalError(): never {
throw new Error("A fatal error occurred. Please restart the app.");
}
Here, the showfatalError()
function always throws an error and never returns, that's why its return type is never
.
We are saying that the showFatalError() function will completely stop the program— it doesn't come back.
The TypeScript will warn you if you accidentally try to return anything. For example,
function showFatalError(): never {
return; // Error: Function with return type 'never' cannot return
}
TypeScript never With Infinite Loops
You can also use the never
type with the functions that run in an infinite loop.
function keepRunning(): never {
while (true) {
console.log("Still running...");
}
}
Here, the function just keeps printing forever. It never finishes, and it never returns a value, not even undefined. That's why the return type is never
.
The keepRunning()
function will not exit under any condition — and it definitely won't return anything.
TypeScript never With Unreachable Code
You can use never
with unreachable code — places in your code that should never be hit if everything is working correctly.
For example, you can use never
in a switch
statement where you've handled all the possible cases.
type Status = "success" | "error";
function handleStatus(status: Status) {
switch (status) {
case "success":
console.log("Success");
break;
case "error":
console.log("Error");
break;
default:
// This is unreachable — all cases are handled above
const unreachable: never = status;
}
}
handleStatus("success");
Here, never
is used to make sure that the default
case is truly unreachable.
If someone adds a new value (like "loading"
) to the Status
type and forgets to handle it in the switch
, TypeScript will throw an error here.
type Status = "success" | "error" | "loading";
function handleStatus(status: Status) {
switch (status) {
case "success":
console.log("Success");
break;
case "error":
console.log("Error");
break;
default:
// This is unreachable — all cases are handled above
const unreachable: never = status;
}
}
handleStatus("loading");
Output
error TS2322: Type '"loading"' is not assignable to type 'never'.
never Vs. void
Both void
and never
are used when functions don't return a value, but they're not the same.
void | never |
---|---|
The function with the void type finishes but returns nothing. |
The function with the never type never finishes at all. |
Normally used with functions that have side effects like logging messages to the console. | Normally used with functions that throw an error or run forever |
Also Read: