Type Guards

`typeof`, `instanceof`, `in` — and Manual Guards

Type Guards

Type guards are the operators TypeScript recognizes for narrowing. Plus a way to write your own.

4 min read Level 2/5 #typescript#type-guards#narrowing
What you'll learn
  • Narrow with `instanceof` and `in`
  • Combine guards
  • Write a user-defined guard

The built-in narrowers TS recognizes. Each one tells TS something specific.

typeof — Primitives

Covered in the previous lesson. Use for string, number, boolean, function, undefined.

instanceof — Class Instances

function describeError(e: Error | string) {
  if (e instanceof Error) {
    // e is Error
    console.log(e.message);
  } else {
    // e is string
    console.log(e);
  }
}

instanceof X narrows to “instance of class X”.

in — Property Existence

type Dog = { bark: () => void };
type Cat = { meow: () => void };

function speak(pet: Dog | Cat) {
  if ("bark" in pet) {
    pet.bark();      // pet is Dog
  } else {
    pet.meow();      // pet is Cat
  }
}

in checks whether a property exists. Useful for distinguishing union members by their unique fields.

Equality Narrowing for Objects

function status(x: { state: "ok" } | { state: "error" }) {
  if (x.state === "ok") {
    // x is { state: "ok" }
  } else {
    // x is { state: "error" }
  }
}

The most useful narrowing — narrowing on a discriminator field. Discriminated unions get a full lesson soon.

Combined Guards

function safe(x: string | number | null) {
  if (x != null && typeof x === "string") {
    // x is string
  }
}

x != null (with !=, not !==) rules out BOTH null and undefined. Then typeof narrows further.

User-Defined Guards

For checks the compiler can’t figure out, write your own — covered in detail next lesson.

Recap

ToolWhen
typeofPrimitive types (string, number, etc.)
instanceofClass instances
inAn object has a specific key
=== / !==Literal-value narrowing
TruthinessRules out falsy values
User-definedCustom checks (next lesson)

Up Next

When the built-in guards aren’t enough — write a function that guarantees a type.

Type Predicates →