Custom Type Guards

Write your own function that narrows a type using an is predicate.

Syntaxfunction isFish(p: Pet): p is Fish { }

A custom type guard is a function whose return type is a type predicate like value is Fish. When it returns true, TypeScript narrows the value to that type.

Type guards are ideal for validating unknown data or distinguishing between object shapes that don't share a class.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • An isUser type guard validates that an unknown API payload has the required id and name fields before treating it as User.
  • A library exports an isError guard so consumers can safely narrow unknown catch values to Error objects.
  • A component uses a custom isAuthenticated guard to narrow a Session | null type before rendering protected content.

More examples

Custom type guard with is

Defines a type guard function returning pet is Fish so TypeScript narrows the union in both if and else branches.

Example · ts
interface Fish  { swim(): void; }
interface Bird  { fly(): void; }

function isFish(pet: Fish | Bird): pet is Fish {
  return (pet as Fish).swim !== undefined;
}

function move(pet: Fish | Bird): void {
  if (isFish(pet)) {
    pet.swim(); // narrowed to Fish
  } else {
    pet.fly();  // narrowed to Bird
  }
}

Guard for unknown API response

Guards an unknown value by checking structural shape properties before asserting it is a User.

Example · ts
interface User { id: number; name: string; }

function isUser(value: unknown): value is User {
  return (
    typeof value === 'object' &&
    value !== null &&
    'id' in value &&
    'name' in value
  );
}

const raw: unknown = { id: 1, name: 'Alice' };
if (isUser(raw)) {
  console.log(raw.name); // safe
}

Array element type guard

Uses a type guard as the filter callback so TypeScript infers the result as string[] instead of unknown[].

Example · ts
function isString(val: unknown): val is string {
  return typeof val === 'string';
}

const mixed: unknown[] = [1, 'hello', null, 'world'];
const strings: string[] = mixed.filter(isString);

console.log(strings); // ['hello', 'world']

Discussion

  • Be the first to comment on this lesson.