CodeWithMihir

TypeScript Tutorial

TypeScript Type Guards Explained

Learn how to create and use TypeScript type guards with value is Type syntax, unknown values, arrays, objects, and practical examples.

Welcome back! I am Mihir, and in this lesson we will learn type guards in TypeScript.

A type guard is a function that checks a value and tells TypeScript what type it is.


Why Type Guards Matter

function printName(value: unknown) {
  console.log(value.name);
}

This is invalid because unknown must be checked before use.

Type guards help you make that check reusable.


Basic Type Guard

type User = {
  name: string;
};

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

The return type is the important part:

value is User

It tells TypeScript that if the function returns true, value is a User.


Using a Type Guard

function printName(value: unknown) {
  if (isUser(value)) {
    console.log(value.name);
  }
}

Inside the if, TypeScript knows value is User.


Type Guard for Strings

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

function format(value: unknown) {
  if (isString(value)) {
    return value.toUpperCase();
  }

  return "Invalid value";
}

Simple type guards can still make code cleaner.


Type Guard for Arrays

function isStringArray(value: unknown): value is string[] {
  return Array.isArray(value) && value.every((item) => typeof item === "string");
}

Usage:

function printTags(value: unknown) {
  if (isStringArray(value)) {
    value.forEach((tag) => console.log(tag.toUpperCase()));
  }
}

Type Guard for Object Properties

type Product = {
  id: number;
  name: string;
};

function isProduct(value: unknown): value is Product {
  if (typeof value !== "object" || value === null) {
    return false;
  }

  return "id" in value && "name" in value;
}

This checks that the properties exist.

For stricter validation, you can also check property value types.


Type Guards with Union Types

type Admin = {
  role: "admin";
  permissions: string[];
};

type Customer = {
  role: "customer";
  orders: number;
};

function isAdmin(user: Admin | Customer): user is Admin {
  return user.role === "admin";
}

Now isAdmin narrows the union.


Quick Recap

  • A type guard is a function that narrows a type.
  • The syntax is value is Type.
  • Type guards are useful with unknown, API data, and unions.
  • Always check that object values are not null.
  • Runtime checks should match the type you are promising.

Next up, we will learn Discriminated Unions →.