TypeScript ยท Chapter 33 of 44

TypeScript Type Guards

A type guard is a function or expression that TypeScript recognizes as reliably checking a value's type. Beyond typeof and instanceof, you can write your own custom type guard functions.

A custom type guard uses a special return type syntax, `parameterName is Type`, which tells TypeScript to narrow the type of the argument to `Type` wherever the guard returns true.

Syntax
function isString(value: unknown): value is string {
  return typeof value === "string";
}

Built-in guards

`typeof`, `instanceof`, and the `in` operator (checking if a property exists on an object) are all built-in ways to narrow types that TypeScript understands automatically.

Custom type guards

You can define a function like `function isFish(pet: Fish | Bird): pet is Fish { ... }`. TypeScript then narrows the type wherever this function is used inside an if condition.

Example 1 (typescript)
function isString(value: unknown): value is string {
  return typeof value === "string";
}
function printIfString(value: unknown) {
  if (isString(value)) {
    console.log(value.toUpperCase());
  }
}
printIfString("hi");
Output
HI

isString is a custom type guard; TypeScript narrows value to string inside the if block.

Example 2 (typescript)
interface Fish { swim(): string; }
interface Bird { fly(): string; }
function isFish(pet: Fish | Bird): pet is Fish {
  return "swim" in pet;
}
function move(pet: Fish | Bird) {
  if (isFish(pet)) {
    console.log(pet.swim());
  } else {
    console.log(pet.fly());
  }
}
move({ swim: () => "Swimming" });
Output
Swimming

The `in` operator checks for the swim property, and isFish narrows the union accordingly.

Key points

  • Type guards are checks that TypeScript uses to narrow types.
  • Built-in guards include typeof, instanceof, and the in operator.
  • Custom type guards use the `parameter is Type` return syntax.
  • Type guards make working with union types safer and clearer.
๐Ÿ’ก Note: Well-named custom type guards make complex conditional logic much easier to read.

๐Ÿ“ Quick Quiz

1. What does a custom type guard return type look like?

2. Which operator checks if a property exists on an object for narrowing?

3. Why write custom type guards?