Let’s unpack void in TypeScript with examples, compare it to undefined, and explain how functions behave when they don’t return a meaningful value. Void vs never vs unknown vs any.
When working with TypeScript, you’ll encounter functions that don’t return anything — for example, logging to the console or updating some state.
In JavaScript, such functions return undefined by default.
In TypeScript, their return type is expressed with the void type.
What is void in TypeScript?
voidrepresents the absence of a return value.- A function with a
voidreturn type means: “This function doesn’t return anything useful.”
Example:
function logMessage(message: string): void {
console.log("LOG:", message);
}
const result = logMessage("Hello TypeScript!");
// result has type void → cannot be used for computation
Here, result is void. Internally, the function returns undefined, but TypeScript ensures you don’t rely on that value.
void vs undefined
In TypeScript:
voidis a wider concept: “nothing meaningful is returned.”undefinedis a specific value in JavaScript.
function returnsUndefined(): undefined {
return undefined; // must explicitly return undefined
}
function returnsVoid(): void {
return; // or just omit return
}
Key points:
- A
voidfunction may returnundefinedimplicitlyfunction f(): void {} console.log(f()); // logs undefined - A
voidfunction cannot guarantee an actualundefinedvalue
TypeScript treatsvoidas “ignore the return value,” whileundefinedis an actual value. - When to use
voidvsundefined- Use
voidfor functions that shouldn’t return anything. - Use
undefinedonly when a function explicitly must return that literal value.
- Use
Example: Event Handlers with void
Many callback functions (like event handlers) are typed with void:
type ClickHandler = (event: MouseEvent) => void;
const handleClick: ClickHandler = (event) => {
console.log("Button clicked:", event.clientX, event.clientY);
};
document.addEventListener("click", handleClick);
Why? Because event handlers don’t return useful values — they perform side effects.
Example: API Functions Returning void
function saveToDatabase(record: object): void {
// Imagine saving to DB here
console.log("Saved:", record);
}
const saved = saveToDatabase({ id: 1 });
// saved is void → cannot be used
This prevents accidental misuse of the return value.
Pitfall: void vs Promise
A subtle detail:
async function asyncVoid(): Promise<void> {
console.log("Async side effect");
}
Promise<void>means the promise resolves, but without a useful value.- It’s not the same as
Promise<undefined>(which explicitly resolves withundefined).
async function returnsUndefined(): Promise<undefined> {
return undefined;
}
Quick Comparison: void vs undefined
| Feature | void | undefined |
|---|---|---|
| Meaning | Absence of a meaningful return value | A specific JS value |
| Return type in functions | Used to say “function does not return anything useful” | Used to say “function must return exactly undefined” |
| Allowed return | Implicit undefined or no return | Must explicitly return undefined |
| Example | function log(): void { console.log("x"); } | function f(): undefined { return undefined; } |
Best Practices with void
✅ Use void for:
- Event handlers
- Logging / side-effect functions
- Async functions that don’t return data
❌ Avoid using undefined in return types unless you really mean “this must always return undefined.”
Conclusion
voidin TypeScript is used for functions that don’t return anything useful.- Internally, they still return
undefined, but TypeScript ensures you don’t rely on it. undefinedas a return type means a function must explicitly return theundefinedvalue.- Use
voidin most cases — it clearly communicates “this function is only about side effects.”
Now let’s make a clear comparing void vs never vs unknown vs any. These types often confuse developers because they all touch on “absence” or “flexibility” in different ways.
void vs never vs unknown vs any in TypeScript
TypeScript has several special types that describe unusual values:
void→ no meaningful return valuenever→ no value at all (function never finishes normally)unknown→ some value, but type unknown (safe version ofany)any→ disables type checking (unsafe)
Let’s compare them in pairs with examples.
1. void vs never
Both void and never are used in function return types, but they mean very different things.
void: Function executes but doesn’t return anything useful.never: Function never returns at all (throws error or runs infinitely).
function logMessage(msg: string): void {
console.log(msg); // returns undefined implicitly
}
function fail(msg: string): never {
throw new Error(msg); // never reaches the end
}
👉 Use void for side-effect functions (logging, updating state).
👉 Use never for error functions or infinite loops.
2. void vs unknown
void: Means “nothing returned.” You cannot use the return value.unknown: Means “something returned, but we don’t know its type yet.”
function doNothing(): void {}
let result = doNothing();
// result: void (cannot use)
let value: unknown = JSON.parse('{"x":10}');
if (typeof value === "object" && value !== null) {
console.log(value); // ✅ safe after check
}
👉 Use void for return types.
👉 Use unknown for variables/data where type is uncertain (e.g., API responses).
3. void vs any
void: Means “ignore the return value.”any: Means “accept any value, do whatever you want.”
function log(): void {
console.log("Side effect");
}
let flexible: any = 42;
flexible = "hello"; // OK
flexible.nonExistentMethod(); // ❌ Runtime crash, TS allows it
👉 Use void for functions with no result.
👉 Avoid any in good projects — use unknown instead.
Master Comparison Table
| Feature | void | never | unknown | any |
|---|---|---|---|---|
| Meaning | “No meaningful return” | “No value, function never returns normally” | “Some value, type unknown” | “Anything (unsafe)” |
| Typical use | Function returns nothing (side effects) | Error functions, infinite loops, exhaustiveness checks | API responses, dynamic input | Legacy JS, temporary escape hatch |
| Assignable from all types? | ❌ No | ❌ No | ✅ Yes | ✅ Yes |
| Assignable to all types? | ✅ Yes (but mostly useless) | ✅ Yes (subtype of all) | ❌ No | ✅ Yes |
| Safety | ✅ Safe | ✅ Strict | ✅ Safe (forces checks) | ❌ Unsafe |
| Example | function log(): void {} | function fail(): never { throw ... } | let v: unknown = JSON.parse(...) | let v: any = JSON.parse(...) |
Quick Summary
void→ Functions that return nothing useful (side effects only).never→ Functions that cannot return at all.unknown→ Safe placeholder for unknown types, must be checked before use.any→ Unsafe escape hatch that bypasses the type system (avoid in production).