Back to roadmaps typescript Course

Mapped Types and Conditional Types

TypeScript provides operators to programmatically transform one type into another. These operations are often referred to as type gymnastics.


1. Mapped Types

A mapped type allows you to create a new type by iterating over a union of keys. It uses a syntax inspired by array map methods.

Syntax

type PropertyFlags<T> = {
  [Property in keyof T]: boolean;
};

interface Features {
  darkMode: () => void;
  notifications: () => void;
}

// Maps all method keys to boolean flags
type FeatureFlags = PropertyFlags<Features>;

Mapping Modifiers

You can add or remove modifiers like readonly or optional status (?) during mapping. Use + or - prefixes.

// Remove readonly modifier from properties
type CreateMutable<T> = {
  -readonly [P in keyof T]: T[P];
};

interface LockedConfig {
  readonly databaseHost: string;
}

type EditableConfig = CreateMutable<LockedConfig>;

2. Conditional Types

Conditional types select one of two types based on a test expressed as a type relationship. They look like ternary operators in JavaScript.

Syntax

// SomeType extends OtherType ? TrueType : FalseType

Basic Example

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

type Test1 = IsString<string>; // true
type Test2 = IsString<number>; // false

3. Distributive Conditional Types

When conditional types act on a generic parameter that is a union type, they automatically distribute across the union members.

type ToArray<Type> = Type extends any ? Type[] : never;

// Distributed: string[] | number[]
type StringOrNumberArray = ToArray<string | number>;

If you want to prevent distribution, wrap the extends expression check in square brackets:

type ToArrayNonDist<Type> = [Type] extends [any] ? Type[] : never;

// Not distributed: (string | number)[]
type CombinedArray = ToArrayNonDist<string | number>;

4. Summary

  • Mapped types transform property configurations by iterating over object keys.
  • Use modifiers like -readonly or -? to strip attributes during type mapping.
  • Conditional types resolve output shapes based on subtype relationships.
  • Generics in conditional types distribute across union members unless wrapped in square brackets.
Published on Last updated: