runtime.boot

Full Stack Systems
Production Mindset

CodeWithMihir

Engineering thoughtful products from interface to infrastructure.

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 →.