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)