TypeScript Type Aliases

Understand type aliases, unions, and intersections to make your TypeScript code more expressive.

TL;DR

  1. 01Create reusable type names with the type keyword.
  2. 02Combine types using unions and intersections for flexibility.
  3. 03Lock values to literals for precise type safety.

Tips

  1. 01Use type aliases for unions and intersections, and use interfaces for object shapes you may want to extend later.

Warnings

  1. 01Type aliases cannot be merged like interfaces, so duplicate names will cause a compiler error.

Basic Syntax

  • Declare a type alias using the type keyword and PascalCase naming.
    type User = {
      id: number;
      name: string;
    };
  • Assign any valid type, including objects, primitives, or other type aliases.
    type ID = number | string;
  • Use the alias anywhere you would normally write the full type expression.
    const user: User = { id: 1, name: "Sam" };
  • Type aliases can describe object shapes much like interfaces can.
  • Keep aliases short and focused to make them easy to reuse.

Union Types

  • Combine types with the pipe symbol for multiple allowed options.
    type ID = string | number;
    const a: ID = "abc";
    const b: ID = 42;
  • Use unions to allow a variable to hold values of different shapes.
  • Narrow union types inside code using typeof or in checks.
    function format(value: string | number) {
      if (typeof value === "string") return value.trim();
      return value.toFixed(2);
    }
  • Build status types from string literals for clear, restricted state.
    type Status = "loading" | "success" | "error";
  • Pass unions as function parameters to accept several valid input types.

Intersection Types

  • Combine multiple types into one using the ampersand symbol between them.
    type Named = { name: string };
    type Aged = { age: number };
    type Person = Named & Aged;
  • Intersections merge all properties from each type into a single shape.
    const sam: Person = { name: "Sam", age: 30 };
  • Use intersections to compose small types into larger object definitions.
  • Conflicting property types in intersections create unusable never values.
  • Prefer intersections over interface extension when working with type aliases.

Literal Types

  • Restrict a value to one exact string, number, or boolean literal.
    type Direction = "up" | "down" | "left" | "right";
  • Combine literal types with unions to create fixed sets of allowed values.
    type Size = "sm" | "md" | "lg";
  • Use literals for things like API methods, sizes, or status codes.
  • Add as const to objects to make all properties literal and readonly.
    const CONFIG = { mode: "prod" } as const;
  • Literal types catch typos that regular string types would silently allow.

Advanced Patterns

  • Use generic type aliases for flexible, reusable type shapes.
    type Box<T> = { value: T };
    const n: Box<number> = { value: 42 };
  • Build conditional types with the ternary-style syntax for advanced logic.
    type IsString<T> = T extends string ? true : false;
  • Use mapped types to transform every key in another type.
    type Optional<T> = { [K in keyof T]?: T[K] };
  • Combine aliases with utility types to build reusable transformation patterns.
  • Export type aliases from a shared file to keep types organized.

FAQ