DEV Community

Cover image for Void vs Undefined in TypeScript: Runtime vs Compile-Time Explained
Arka Chakraborty
Arka Chakraborty

Posted on

Void vs Undefined in TypeScript: Runtime vs Compile-Time Explained

🔥 Intro

When a TypeScript function doesn’t return anything, does it return voidor undefined?
At runtime, JavaScript always gives you undefined.
At compile-time, TypeScript shows void.
Let’s unpack this apparent contradiction.


🕹 Runtime (JavaScript) Perspective

JavaScript doesn’t have void. Every function call evaluates to something.
If you don’t return explicitly, it evaluates to undefined.

function greet(name: string) { console.log(`Hello, ${name}!`); } console.log(greet("Arka")); // Output: // Hello, Arka! // undefined 
Enter fullscreen mode Exit fullscreen mode

👉 At runtime, the actual return value is always undefined.


đź›  Compile-Time (TypeScript) Perspective

TypeScript isn’t executing your code. It’s describing intent at compile-time.
When you don’t return anything, TypeScript marks the return type as void.

function greet(name: string): void { console.log(`Hello, ${name}!`); } const result = greet("Arka"); // result has type void (not undefined) 
Enter fullscreen mode Exit fullscreen mode

👉 At compile-time, void means:
“Don’t rely on or use the return value.”


❌ Why Not Just undefined?

Let’s try making the return type undefined:

function greet(name: string): undefined { console.log(`Hello, ${name}!`); } 
Enter fullscreen mode Exit fullscreen mode

⚡ Compile-time error:

Function lacks ending return statement and return type does not include 'undefined' 
Enter fullscreen mode Exit fullscreen mode

Because if you use undefinedas a type, TypeScript expects you to explicitly return undefined:

function doNothing(): undefined { return undefined; // âś… valid } 
Enter fullscreen mode Exit fullscreen mode

So:

  • Runtime value: undefined
  • Compile-time type: void(unless you explicitly force undefined)

đźš© Async Functions

The same rule applies for async functions:

async function greetAsync(name: string): Promise<void> { console.log(`Hello, ${name}!`); } 
Enter fullscreen mode Exit fullscreen mode
  • At runtime: returns Promise.resolve(undefined)
  • At compile-time: return type is Promise<void>

Arrow version:

const greetAsync = async (name: string): Promise<void> => { console.log(`Hello, ${name}!`); }; 
Enter fullscreen mode Exit fullscreen mode

🏗 Real-Life Example

function logger(message: string): void { console.log(`[LOG]: ${message}`); } async function saveData(data: string): Promise<void> { await new Promise(res => setTimeout(res, 1000)); logger(`Saved: ${data}`); } 
Enter fullscreen mode Exit fullscreen mode
  • Runtime: logger returns undefined, saveData resolves to undefined.
  • Compile-time: TypeScript shows voidand Promise<void>.

đź’ˇ Key Takeaways

  • Runtime (JavaScript): No-return functions → always return undefined.
  • Compile-time (TypeScript): Uses void(or Promise<void>) to signal “don’t use the return value.”
  • undefinedas a type: Too strict; requires explicit return undefined;.
  • Rule of Thumb: Use voidfor functions with no meaningful return.
  • So, next time you see voidin TypeScript, remember: it’s a compile-time abstraction, while undefinedis the actual runtime value.

Top comments (0)