TypeScriptTypeScript17 min read

Type Guards and Narrowing

Learn how to narrow union types safely using typeof, instanceof, and custom type guards.

David Miller
Dec 20, 2025
6,597290

Type guards tell TypeScript: what type you have right now.

  ## typeof guard
  
  ```ts
  function print(val: number | string) {
    if (typeof val === "string") {
      console.log(val.toUpperCase());
    } else {
      console.log(val.toFixed(2));
    }
  }
  ```
  
  ## instanceof guard
  
  ```ts
  class User {
    name = "Tom";
  }
  
  function check(x: User | Date) {
    if (x instanceof User) {
      console.log(x.name);
    } else {
      console.log(x.getFullYear());
    }
  }
  ```
  
  ## Custom type guard
  
  ```ts
  type Cat = { meow: () => void };
  type Dog = { bark: () => void };
  
  function isCat(pet: Cat | Dog): pet is Cat {
    return (pet as Cat).meow !== undefined;
  }
  ```
  
  ## Graph
  
  ```mermaid
  flowchart TD
    A[Union] --> B{Check}
    B -->|string| C[String branch]
    B -->|number| D[Number branch]
  ```
  
  ## Remember
  - Guards make unions usable
  - Prevent runtime mistakes
  
#TypeScript#Beginner#Type Guards