Void and Never: Special Function Return Types

Table of Contents

  • Introduction
  • What is the void Type?
    • Use Cases for void
    • Example Code
  • What is the never Type?
    • Use Cases for never
    • Example Code
  • Differences Between void and never
  • When to Use void and never
  • Best Practices for Using void and never
  • Conclusion

Introduction

TypeScript provides several advanced features that make it a more robust and safer programming language than JavaScript. One such feature is the ability to define special return types for functions. Two of the most intriguing return types in TypeScript are void and never. These types might seem similar at first glance because they both represent the idea of “no value” in some capacity, but they are fundamentally different and serve distinct purposes.

In this article, we will explore what the void and never types are, their use cases, differences, and when and how to use them effectively. By understanding these special function return types, you’ll be able to write cleaner, more precise TypeScript code.


What is the void Type?

The void type is used in TypeScript to represent the absence of a return value from a function. It indicates that the function doesn’t return anything. While it might seem similar to undefined, void is explicitly used for functions that don’t need to return anything, such as event handlers or callbacks.

In TypeScript, a function with a void return type will not return a value, and trying to do so will result in a compile-time error.

Use Cases for void

  • Event Handlers and Callbacks: Functions that are invoked as callbacks or event handlers often don’t return a value, so their return type should be void.
  • Non-returning Functions: Functions that perform actions but don’t need to return a value, such as logging or performing side effects, should have the void return type.

Example Code

function greet(name: string): void {
console.log(`Hello, ${name}!`);
}

greet("John"); // OK
greet("John") + 5; // Error: Operator '+' cannot be applied to a void type

In this example, the greet function does not return anything, so its return type is void. If we try to use its result in an expression like greet("John") + 5, TypeScript will throw an error because the return type of the function is not a value that can be used in arithmetic.


What is the never Type?

The never type is a more specialized type in TypeScript. It represents the type of values that never occur. Functions that return never are functions that do not complete normally. These can include functions that throw an error or functions that enter an infinite loop.

In other words, a function with a never return type can never reach a normal completion state. It either throws an error or never returns at all (e.g., in an infinite loop).

Use Cases for never

  • Throwing Errors: Functions that throw exceptions without returning any value are ideal candidates for the never return type.
  • Infinite Loops: Functions that contain infinite loops, which never allow the function to finish or return, should use the never type.
  • Exhaustiveness Checking: The never type can also be used in exhaustive checks, ensuring that all possible values are handled in a switch case or if-else block.

Example Code

function throwError(message: string): never {
throw new Error(message);
}

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

throwError("Something went wrong!"); // OK
infiniteLoop(); // OK

In this example, throwError is a function that throws an error, and since it doesn’t return a value, its return type is never. The infiniteLoop function runs indefinitely, so it also has a never return type.


Differences Between void and never

Although both void and never are used for functions that do not return a value, they have key differences:

Aspectvoidnever
Return ValueFunction explicitly returns undefined or does not return at all.Function never returns and either throws an error or has an infinite loop.
Use CasesUsed for functions that have no meaningful return value, like event handlers and callbacks.Used for functions that do not complete normally (e.g., throw errors, infinite loops).
Type InferenceTypeScript infers the return type as void when there is no return statement in the function body.TypeScript infers the return type as never for functions that never return.
Examplefunction logMessage(message: string): void { console.log(message); }function throwError(message: string): never { throw new Error(message); }

When to Use void and never

Both void and never are essential for improving the type safety and clarity of your code, but they are used in different situations.

Use void When:

  • You have a function that doesn’t return a value, like logging or event handling.
  • You want to explicitly indicate that a function has no meaningful return value.

Use never When:

  • A function is designed to throw an error and never return a value (e.g., error handling).
  • A function contains an infinite loop or is otherwise not expected to terminate.
  • You are performing exhaustive checks in switch-case statements or other control flow mechanisms to ensure all cases are covered.

Best Practices for Using void and never

  • Use void for non-returning functions: Functions like callbacks, event handlers, and logging functions that don’t need to return a value should use the void return type.
  • Use never for functions that throw errors or have infinite loops: For functions that are designed to throw exceptions or run forever, use the never return type to indicate that they don’t complete normally.
  • Leverage never in exhaustive checks: When handling union types, especially in switch-case statements, use never to ensure that all possible cases are covered.
type Animal = { type: "dog"; bark: () => void } | { type: "cat"; meow: () => void };

function handleAnimal(animal: Animal): void {
switch (animal.type) {
case "dog":
animal.bark();
break;
case "cat":
animal.meow();
break;
default:
// The 'never' type guarantees we don't miss any cases
throw new Error("Unknown animal type!");
}
}

Conclusion

The void and never types in TypeScript are powerful tools that allow you to explicitly define the return types of functions that don’t return values. While void is used for functions that don’t return a meaningful value, never is used for functions that either throw an error or never return because of an infinite loop.

Understanding when and how to use these types can improve the clarity, type safety, and maintainability of your TypeScript code. By using these special return types appropriately, you can ensure that your code behaves as expected and prevent common runtime errors.