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

TS Narrowing

Narrowing is how TypeScript refines a wide type (like string | number) down to a specific one inside a branch. The compiler tracks what you've ruled out.

typeof guards

TS
function format(value: string | number): string {
    if (typeof value === 'string') {
        return value.toUpperCase();   // value: string
    }
    return value.toFixed(2);          // value: number
}

truthiness narrowing

TS
function len(s?: string): number {
    if (!s) return 0;        // s narrowed to undefined here
    return s.length;          // s: string
}

Equality narrowing

TS
function example(x: string | number, y: string | boolean) {
    if (x === y) {
        // x and y both narrowed to string
        return x.toUpperCase();
    }
}

in operator

TS
type Fish = { swim(): void };
type Bird = { fly():  void };

function move(animal: Fish | Bird) {
    if ('swim' in animal) {
        animal.swim();    // Fish
    } else {
        animal.fly();      // Bird
    }
}

instanceof

TS
function check(d: Date | string) {
    return d instanceof Date ? d.toISOString() : d;
}

Discriminated unions

The most powerful pattern — give each union member a literal tag:

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

function area(s: Shape) {
    switch (s.kind) {
        case 'circle': return Math.PI * s.radius ** 2;
        case 'rect':   return s.w * s.h;
    }
}
Tip: If a switch over a discriminated union forgets a case, TS will warn — assign the variable to a never in the default branch to make the check explicit.

Example

Example
function format(value: string | number): string {
  if (typeof value === 'string') {
    return value.toUpperCase();   // narrowed to string
  }
  return value.toFixed(2);        // narrowed to number
}
console.log(format('hi'), format(3.14));
Try it Yourself »

Exercise

Operator that narrows a primitive in an if.

if ( value === 'string') {}

Test yourself

Q1. In "if (typeof x === 'string')" TS narrows x to…
Q2. Discriminated unions narrow inside…
Q3. Exhaustiveness check uses the type…

Discussion

Loading…