Uncategorized

void in TypeScript – Functions That Return Nothing

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?

  • void represents the absence of a return value.
  • A function with a void return 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:

  • void is a wider concept: “nothing meaningful is returned.”
  • undefined is a specific value in JavaScript.
function returnsUndefined(): undefined {
  return undefined; // must explicitly return undefined
}

function returnsVoid(): void {
  return; // or just omit return
}

Key points:

  1. A void function may return undefined implicitly function f(): void {} console.log(f()); // logs undefined
  2. A void function cannot guarantee an actual undefined value
    TypeScript treats void as “ignore the return value,” while undefined is an actual value.
  3. When to use void vs undefined
    • Use void for functions that shouldn’t return anything.
    • Use undefined only when a function explicitly must return that literal value.

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 with undefined).
async function returnsUndefined(): Promise<undefined> {
  return undefined;
}

Quick Comparison: void vs undefined

Featurevoidundefined
MeaningAbsence of a meaningful return valueA specific JS value
Return type in functionsUsed to say “function does not return anything useful”Used to say “function must return exactly undefined
Allowed returnImplicit undefined or no returnMust explicitly return undefined
Examplefunction 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

  • void in 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.
  • undefined as a return type means a function must explicitly return the undefined value.
  • Use void in 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 value
  • never → no value at all (function never finishes normally)
  • unknown → some value, but type unknown (safe version of any)
  • 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

Featurevoidneverunknownany
Meaning“No meaningful return”“No value, function never returns normally”“Some value, type unknown”“Anything (unsafe)”
Typical useFunction returns nothing (side effects)Error functions, infinite loops, exhaustiveness checksAPI responses, dynamic inputLegacy 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
Examplefunction 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).