Caller-Says-Doesn't-Care, Not "Returns Nothing"
`void` Return
`void` as a return type means "the caller won't use the return". Subtler than it sounds — and the source of some classic confusion.
What you'll learn
- Tell `void` from `undefined`
- Understand "covariant return" with `void`
- Recognize why `forEach((x) => arr.push(x))` typechecks
void as a return type is subtle. It means “the caller won’t
use the return value” — not “the function MUST return nothing”.
The Surprise
type Callback = () => void;
const fn: Callback = () => 42; // ✓ — returning 42 is allowed A function returning 42 is assignable to () => void. The
“return type” of void is a contract about callers, not about the
function’s body.
Why It Helps — forEach
Array.forEach’s callback is typed (item: T, ...) => void. If
void meant “must return undefined”, THIS would error:
const arr2: string[] = [];
["a", "b"].forEach(x => arr2.push(x));
// ~~~~~~ push returns a number — would error But void is loose — push returning a number is fine because
forEach doesn’t read the return value. The pattern just works.
When You DO Want “Returns Nothing”
If you genuinely require the function to return undefined, type
it that way:
type StrictCallback = () => undefined; Rare. Most of the time, void is what you want.
In an Annotated Function
function log(msg: string): void {
console.log(msg);
// return 42; // ✗ Type 'number' is not assignable to type 'void'.
} In a function with an EXPLICIT void return, you can’t return a
value. The asymmetry is:
- Annotating
voidon the function: you can’t return a value - Assigning a function to a
() => voidtype: the implementation CAN return anything; callers can’t read it
void vs undefined — Quick Reference
| Use | When |
|---|---|
: void | Caller doesn’t read the return |
: undefined | Return must be undefined |
| No annotation | Let inference decide |
Up Next
The last function lesson — predicates that narrow.
Predicate Functions →