🇬🇧 Limited Time — UK Only·🎓 Free Learning for 1 Month·🤖 Free AI Training Included·📚 4,000+ Lessons · 35,000+ Quizzes·🏆 GCSE Mocks · Olympiad Papers·⚡ Selected Students Only · Limited Places·🎁 Free Value Worth £2,000·🇬🇧 Limited Time — UK Only·🎓 Free Learning for 1 Month·🤖 Free AI Training Included·📚 4,000+ Lessons · 35,000+ Quizzes·🏆 GCSE Mocks · Olympiad Papers·⚡ Selected Students Only · Limited Places·🎁 Free Value Worth £2,000·🇬🇧 Limited Time — UK Only·🎓 Free Learning for 1 Month·🤖 Free AI Training Included·📚 4,000+ Lessons · 35,000+ Quizzes·🏆 GCSE Mocks · Olympiad Papers·⚡ Selected Students Only · Limited Places·🎁 Free Value Worth £2,000·
📘 TypeScript

Return types and void

📚 What are Return Types and void in TypeScript? TypeScript lets you declare exactly what a function returns. This is useful for documentation and catching mistakes: if you say a function returns number but accidentally return a string, TypeScript catches it. void is the return type for functions t…

8 min 10 XP Lesson 13 of 21
Return types and void
🌐

Appy Says…

Some functions exist purely for their side effects — they run code but return nothing meaningful. TypeScript uses void to express this, and never to mark functions that shouldn't return at all. Knowing the difference matters.

📖

What are void and never?

void is the return type for functions that perform side effects but return no useful value. never is the return type for functions that never return (always throw or loop forever).

  • function log(msg: string): void { console.log(msg); }
  • void: function returns undefined implicitly (TypeScript ignores the return value)
  • never: function fail(msg: string): never { throw new Error(msg); }
  • never: infinite loop: function listen(): never { while(true) { ... } }
  • void vs undefined: void means 'ignore the return'; undefined means 'returns undefined specifically'
  • never in union types: string | never simplifies to string
🎮

Think of it like Minecraft redstone signals

Some redstone components give you a signal (return a value). Some just do work — a piston extends without giving you a signal back (void). And some can never complete because they're stuck in an infinite loop or immediately crash (never).

⚙️

How It Works

  • 1. void function: executes code, returns nothing useful, TypeScript doesn't let you use the return value
  • 2. Arrow: const onClick = (): void => { setCount(c + 1); };
  • 3. never function: throws unconditionally OR loops forever
  • 4. TypeScript uses never in exhaustive checks: the default branch of a switch over a union type
  • 5. assertNever(x: never): never pattern catches missed cases at compile time
  • 6. If a function's type is inferred as never, it means TypeScript thinks it can never be called
🌍

Real-World Examples

  • Event handler: onClick: (e: MouseEvent) => void
  • Throw helper: function assertDefined<T>(val: T | undefined): asserts val is T { if (!val) throw new Error('...'); }
  • Exhaustive switch: default case calls assertNever(status) to catch unhandled union members
  • React effect cleanup: useEffect(() => { ... return () => {} }, []); — cleanup is void
💡

Key Facts

  • never is the bottom type — no value is ever of type never
  • void is assignable to undefined but not vice versa in strict mode
  • The exhaustive never pattern is the best way to ensure you handle all cases in a discriminated union switch
  • async functions that always reject return Promise<never>
⚠️

Watch Out!

If TypeScript infers a function's return type as never when you expected it to return a value, it means TypeScript has determined the function always throws or always hits an infinite loop. Don't suppress — investigate why TypeScript thinks the function never completes.

📌

Remember

void = runs side effects, returns nothing meaningful. never = never returns (throws or loops). Use never in exhaustive switch defaults to catch missed union members at compile time.

What You Learned

  • void: function runs but returns no useful value; never: function never returns
  • Exhaustive never pattern catches unhandled discriminated union cases at compile time
  • Unlocks: correct event handler types, safe throw helpers, complete switch statements

Key Facts

  • never is the bottom type — no value is ever of type never
  • void is assignable to undefined but not vice versa in strict mode
  • The exhaustive never pattern is the best way to ensure you handle all cases in a discriminated union switch
  • async functions that always reject return Promise<never>

Real-World Examples

• Event handler: <code>onClick: (e: MouseEvent) => void</code> • Throw helper: <code>function assertDefined&lt;T&gt;(val: T | undefined): asserts val is T { if (!val) throw new Error('...'); }</code> • Exhaustive switch: default case calls <code>assertNever(status)</code> to catch unhandled union members • React effect cleanup: <code>useEffect(() => { ... return () => {} }, []);</code> — cleanup is void

Remember

void = runs side effects, returns nothing meaningful. never = never returns (throws or loops). Use never in exhaustive switch defaults to catch missed union members at compile time.

Quick Quiz

1 / 2

void means?