Mapped & Conditional Types

Master meta-programming in TypeScript to construct dynamic types based on existing type structures.

1. Mapped Types (`[K in keyof T]`)

Mapped types iterate over keys of an existing type to transform property types or modifiers:

type OptionsFlags<T> = {
  [K in keyof T]: boolean;
};

interface Features {
  darkMode: string;
  newUserOnboarding: string;
}

// Every feature property is converted into a boolean flag!
type FeatureFlags = OptionsFlags<Features>;
// Equivalent to: { darkMode: boolean; newUserOnboarding: boolean; }

2. Conditional Types (`T extends U ? X : Y`)

Conditional types select one of two possible types based on a condition expressed as a type relationship test:

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

type A = IsString<string>; // true
type B = IsString<number>; // false

3. Extracting Types with `infer`

The infer keyword enables extracting nested return types or element types dynamically inside a conditional type:

// Extract function return type using infer R
type UnpackReturnType<T> = T extends (...args: any[]) => infer R ? R : never;

function getUserData() {
  return { id: 101, username: "Alice" };
}

// Automatically extracts { id: number; username: string }
type UserData = UnpackReturnType<typeof getUserData>;

Next Up

Learn ES Modules, type-only imports (`import type`), namespaces, and declaration merging.

Next Lesson: Modules & Type Imports →