Beyond basics, TypeScript offers powerful type-level programming. These features help you model complex APIs and build flexible abstractions.

Union Types

A value can be one of several types:

  type ID = string | number;
type Result = 'success' | 'failure' | 'pending';

function printId(id: ID): void {
    if (typeof id === 'string') {
        console.log(id.toUpperCase());
    } else {
        console.log(id.toFixed(0));
    }
}
  

String literal unions are common for finite sets of options:

  type Theme = 'light' | 'dark' | 'system';

function setTheme(theme: Theme): void {
    document.body.dataset.theme = theme;
}
  

Intersection Types

Combine multiple types into one:

  interface Named {
    name: string;
}

interface Aged {
    age: number;
}

type Person = Named & Aged;

const alice: Person = { name: 'Alice', age: 30 };

interface Timestamped {
    createdAt: Date;
    updatedAt: Date;
}

type User = Named & Aged & Timestamped;
  

Intersections merge properties; conflicts on the same property must be compatible.

Mapped Types

Transform properties of an existing type:

  type Readonly<T> = {
    readonly [K in keyof T]: T[K];
};

type Optional<T> = {
    [K in keyof T]?: T[K];
};

interface Todo {
    title: string;
    done: boolean;
}

type ReadonlyTodo = Readonly<Todo>;
// { readonly title: string; readonly done: boolean; }
  

Add or remove modifiers with + and -:

  type Mutable<T> = {
    -readonly [K in keyof T]: T[K];
};
  

Conditional Types

Types that depend on a condition:

  type IsString<T> = T extends string ? true : false;

type A = IsString<'hello'>;  // true
type B = IsString<42>;       // false

type Flatten<T> = T extends Array<infer U> ? U : T;

type Str = Flatten<string[]>;  // string
type Num = Flatten<number>;     // number
  

infer Keyword

Extract types within conditional types:

  type ReturnType<T> = T extends (...args: unknown[]) => infer R ? R : never;

type Fn = () => string;
type R = ReturnType<Fn>;  // string
  

Template Literal Types

Build string types programmatically:

  type EventName = 'click' | 'focus' | 'blur';
type Handler = `on${Capitalize<EventName>}`;
// 'onClick' | 'onFocus' | 'onBlur'

type Route = `/${string}`;

const home: Route = '/home';
const about: Route = '/about';
// const bad: Route = 'home'; // Error — must start with /
  

Advanced types unlock precise modeling of libraries and frameworks. Next, we apply TypeScript to React development.