Course

TypeScript Never: Syntax, Usage, and Examples

The never type in TypeScript represents values that never occur. Functions that throw errors, infinite loops, or cases where no value can be returned use never. Unlike void, which signals the absence of a return value, never ensures that execution never successfully completes.

How to Use Never in TypeScript

Declaring a Function That Returns Never

Use never when a function throws an error or has an unreachable endpoint.

tsx
function throwError(message: string): never { throw new Error(message); } throwError("Something went wrong!");

The function above never returns a value because it throws an error, making never the appropriate return type.

Infinite Loops and Never

A function that enters an endless loop without an exit condition should also return never.

tsx
function infiniteLoop(): never { while (true) { console.log("Running forever..."); } }

Since this function never terminates, it can only be assigned a never type.

Never in Exhaustive Type Checks

The never type helps ensure all possible cases are handled in a switch statement. If an unexpected value appears, TypeScript throws an error.

tsx
type Status = "success" | "error"; function handleStatus(status: Status): void { switch (status) { case "success": console.log("Operation successful!"); break; case "error": console.log("An error occurred."); break; default: assertNever(status); } } function assertNever(value: never): never { throw new Error(`Unexpected value: ${value}`); }

If a new status value is added to Status but not handled in the switch statement, TypeScript catches the error at compile time.

When to Use Never in TypeScript

Functions That Always Throw Errors

If a function throws an error instead of returning a value, it should have a return type of never.

tsx
function fail(): never { throw new Error("This function always fails!"); }

Functions That Never Terminate

A function that runs indefinitely without stopping should return never.

tsx
function keepRunning(): never { while (true) { console.log("Still running..."); } }

Exhaustive Type Checking

The never type helps validate that all cases in a switch statement are covered.

tsx
type Mode = "light" | "dark"; function setTheme(mode: Mode): void { switch (mode) { case "light": console.log("Light mode activated."); break; case "dark": console.log("Dark mode activated."); break; default: assertNever(mode); } }

Using never in the default case prevents unhandled values from slipping through unnoticed.

Examples of Never in TypeScript

Using Never in a Function That Crashes

If a function should always result in an error, mark it with never.

tsx
function crash(): never { throw new Error("Unexpected crash!"); }

Ensuring a Function Never Completes

A function that enters an infinite loop without returning should be marked as never.

tsx
function endlessProcess(): never { while (true) { console.log("Processing..."); } }

Validating Exhaustive Type Checks

When working with union types, never ensures that all possible values are handled correctly.

tsx
type Color = "red" | "green" | "blue"; function processColor(color: Color): void { switch (color) { case "red": console.log("Red selected."); break; case "green": console.log("Green selected."); break; case "blue": console.log("Blue selected."); break; default: assertNever(color); } }

If Color is later expanded to include "yellow", TypeScript will flag an error unless the new value is explicitly handled.

Learn More About Never in TypeScript

Never vs. Void

  • void means a function does not return a meaningful value, but it still completes execution.
  • never means a function never successfully reaches an end, either due to an error or an infinite loop.
tsx
function logMessage(): void { console.log("Logging a message."); } function throwErrorMessage(): never { throw new Error("This will never return!"); }

Never in Type Assertions

The never type prevents assigning invalid values when using assertions.

tsx
let value: never; value = "This will cause an error"; // TypeScript error: Type 'string' is not assignable to type 'never'.

Using Never in Generic Functions

The never type is useful when working with generics to prevent invalid assignments.

tsx
function processValue<T>(value: T): T { if (typeof value === "never") { throw new Error("Unexpected value!"); } return value; }

Never in TypeScript Reduce

If an array should never be empty when using reduce(), you can enforce that with never.

tsx
const numbers: number[] = [1, 2, 3]; const total: number = numbers.reduce((sum, num) => sum + num, 0); const emptyArray: never[] = []; // Prevents reducing an empty array

Never in TypeScript Arrays

You can explicitly type an array as never[] to indicate it should always be empty.

tsx
const empty: never[] = []; empty.push(1); // Error: Argument of type '1' is not assignable to type 'never'.

Never in Union Types

When filtering out values from a union type, never helps ensure only valid cases remain.

tsx
type Data = string | number | never; // 'never' is automatically removed const value: Data = 42; // Allowed

The never type in TypeScript ensures that functions never return, either due to errors, infinite loops, or exhaustive type checks. Unlike void, which allows functions to return undefined, never guarantees that execution will not complete successfully.