iwantcoding.com
🔥 Daily 👥 Rooms 🏆 Top Log in Sign up

TS Union Types

A union type lets a value be one of several types: A | B | C. It models "this could be either" — the most common shape for real-world data.

Basics

TS
type Id = number | string;

function lookup(id: Id) {
    // Common methods are available
    return id.toString();
    // id.toUpperCase()  ✗ — not on number
    // id.toFixed(2)     ✗ — not on string
}

You can only use members that exist on every type in the union — narrow with a guard before reaching for specifics.

Narrowing

TS
function lookup(id: Id) {
    if (typeof id === 'string') {
        return id.toUpperCase();   // string
    }
    return id.toFixed(0);          // number
}

Union of literal types

TS
type Direction = 'up' | 'down' | 'left' | 'right';

function move(d: Direction) {
    console.log('Moving', d);
}
move('up');         // OK
// move('upward');  // ✗ error

Discriminated unions

Add a literal "tag" field and TS can narrow inside a switch:

TS
type Shape =
    | { kind: 'circle'; r: number }
    | { kind: 'rect';   w: number; h: number };

function area(s: Shape) {
    switch (s.kind) {
        case 'circle': return Math.PI * s.r ** 2;
        case 'rect':   return s.w * s.h;
    }
}

Exhaustiveness check

Assign the unmatched case to never — TS will error if you ever add a new variant and forget to handle it:

TS
function area(s: Shape): number {
    switch (s.kind) {
        case 'circle': return Math.PI * s.r ** 2;
        case 'rect':   return s.w * s.h;
        default: {
            const _exhaustive: never = s;
            throw new Error('unhandled: ' + JSON.stringify(s));
        }
    }
}
Tip: Discriminated unions are TypeScript's superpower. Any time you've used a boolean flag like isLoading: boolean; data?: T; error?: Error, ask whether { status: 'idle' } | { status: 'loading' } | … would be cleaner.

Example

Example
type Id = number | string;

function lookup(id: Id) {
  return typeof id === 'string' ? id.toLowerCase() : id.toFixed(0);
}
console.log(lookup(42), lookup('ABC'));
Try it Yourself »

Exercise

Operator that joins types in a union.

type Id = number string;

Test yourself

Q1. On a value typed "string | number" you can call…
Q2. Discriminated unions add…
Q3. For three+ OR-equal checks on a single value prefer…

Discussion

Loading…