Special Types

`void`, `never`, `unknown`, `any` — Pick the Right One

Special Types

Four special types — each with a specific meaning. Learn what each one means, and pick `unknown` over `any` almost always.

5 min read Level 2/5 #typescript#void#never
What you'll learn
  • Tell `void` from `undefined`
  • Use `unknown` instead of `any`
  • Recognize where `never` shows up

Four “special” types each play a different role. Knowing when to reach for each is half of writing good TS.

void — Function Returns Nothing

function log(msg: string): void {
  console.log(msg);
}

void says “this function isn’t expected to return a useful value”. You can still return from the function — just not a value that callers should use.

A callback typed as () => void can return anything; callers just won’t see it.

never — A Value That Never Happens

function fail(msg: string): never {
  throw new Error(msg);
}

A function that always throws (or loops forever) returns never. It also shows up in exhaustive switch statements (covered in discriminated unions).

never is “no value will EVER satisfy this type”. It’s the bottom type — assignable to every other type, but only never itself is assignable to never.

unknown — Safe any

function parse(json: string): unknown {
  return JSON.parse(json);
}

const data = parse(text);

data.foo;
//   ~~~ Object is of type 'unknown'.

unknown is “I don’t know what this is — and TypeScript should force me to check before using it.” Compare to any, which disables type checking entirely.

To use unknown, narrow it:

if (typeof data === "string") {
  data.toUpperCase();   // ✓ narrowed to string
}

if (typeof data === "object" && data !== null && "name" in data) {
  // data is now { name: unknown }
}

unknown is what any should have been.

any — Type Checking Off

let x: any = "hi";
x = 42;
x.toUpperCase();    // ✓ — TS doesn't check
x.foo.bar.baz();    // ✓ — TS doesn't check
x();                 // ✓ — TS doesn't check

any opts out of type checking. The escape hatch — useful when gradually adopting TS or when types just don’t exist.

null and undefined

With strictNullChecks (part of strict), these are their own types:

let x: string = null;
//  ~  Type 'null' is not assignable to type 'string'.

let y: string | null = null;   // ✓ allow it explicitly

The strict null check is one of the most important TS features. Always leave it on.

Quick Reference

TypeWhen to use
voidA function that returns nothing useful
neverA function that never returns (throws / infinite)
unknownA value of an unknown type — must check before using
anyEscape hatch — turns off type checking
nullExplicitly missing value
undefinedUninitialized / missing optional property

Up Next

Narrowing — how TS figures out what type something is at each point in your code.

Narrowing →