Skip to content
Theory · Primitive and special types · lesson 7 of 8

void and never

Calling a function is like exchanging parcels. You send the arguments, and the function sends back a return parcel: the result. The result type goes after the parentheses: ): number promises that a number comes back.

Some functions have nothing to send back. One prints a line on the screen and finishes its work: the return parcel arrives empty. Another always throws an error: the return parcel never arrives. TypeScript has the types void and never for these two cases.

void: an empty reply

The type void as a function's result means "there is no useful result". The function does its work and returns nothing:

TypeScript
function logLine(text: string): void {
    console.log("> " + text);
}
const result = logLine("start"); // > start
console.log(result); // undefined

Let's walk through the example line by line:

  1. logLine is declared with the result type void.
  2. The call logLine("start") prints > start.
  3. result receives whatever the function returned. The function has no return, so JavaScript returns undefined.
  4. console.log(result) prints undefined.

So the empty parcel does arrive, and it holds undefined. The type void does not say "this is undefined"; it says "do not use the result". The editor's tooltip shows the type void for result.

You have met void already, even if you did not notice it. Hover over log in console.log: the tooltip shows : void after the parentheses. The method prints text and returns no useful result.

You may leave out the void annotation: if a function has no return with a value, TypeScript infers void on its own. With the annotation, though, tsc checks that the function really returns nothing:

TypeScript
function logLine(text: string): void {
    console.log("> " + text);
    return text.length; // ✗
}
TEXT
error TS2322: Type 'number' is not assignable to type 'void'.

never: no reply at all

The type never means "the function never finishes normally". Most often such a function always throws an error:

TypeScript
function fail(message: string): never {
    throw new Error(message);
}
function toPercent(part: number, whole: number): number {
    if (whole === 0) {
        return fail("whole is zero");
    }
    return (part / whole) * 100;
}
console.log(toPercent(1, 4)); // 25

Let's walk through the example:

  1. fail throws an Error and never reaches the end of its body, so its result is never.
  2. toPercent promises a number, yet one branch returns fail(...). tsc accepts this: a value of type never never appears, so it fits every type.
  3. The call toPercent(1, 4) takes the second branch and prints 25.

The type never also suits a function with an endless while (true) loop and no break: it does not return either. But for a declaration of such a function, or of one that only throws, TypeScript itself infers void rather than never. That is why you write never explicitly.

Here the parcel picture stops working. The return parcel from fail never arrives, but the thrown error is not lost: a try/catch further up the chain of calls can catch it.

Interviewers often ask: "How does void differ from never?"

  • void: the function finishes but returns no useful result, and the calling code gets undefined;
  • never: the function does not finish at all; it throws an error or runs forever.

Common mistake

never was written to mean "returns nothing":

TypeScript
function logLine(text: string): never { // ✗
    console.log(text);
}
TEXT
error TS2534: A function returning 'never' cannot have a reachable end point.

The message says that a function of type never must not reach the end of its body. But logLine does: it prints a line and finishes. Such a function needs void.

Key points

  • void as a result means "no useful result": the function finishes, and the calling code gets undefined.
  • With a void annotation the compiler does not let the function return a value.
  • never means the function does not finish normally: it always throws an error or runs forever.
  • A function that reaches the end of its body cannot be typed never: tsc answers with error TS2534.