Glossary / Mapped types

Mapped types

Mapped types construct a new object type by iterating over a union of property keys and transforming each property's name, value type, or modifiers. They underpin utility types such as Partial, Readonly, and Pick, and allow APIs to preserve relationships between an input shape and a transformed result.

Key iteration and modifiers

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

keyof T produces a union of keys, and indexed access T[K] gets each property's type. Mapped types can add or remove readonly and optional modifiers using + or -, and key remapping with as can rename or filter keys. Mapping over a union can preserve discriminated variants in nuanced ways; distributive helpers may be needed to transform each member independently.

Mapped types express compile-time transformations only. They do not clone objects, freeze values, or remove properties at runtime. Readonly<T> prevents assignments through a particular static view but is shallow unless recursively defined and does not freeze the underlying object.

Design guidance

Use mapped types to preserve shape and avoid duplicating declarations, but keep transformations comprehensible. Recursive mappings can hit compiler recursion/complexity limits and become hard to debug. Consider explicit domain types when property transformations obscure intent. Validate runtime immutability or data transformation separately.

Interview questions

  1. What does keyof T provide? A union of property keys that can drive a mapping.
  2. How remove optionality? Use -? on the mapped property modifier.
  3. Does Readonly<T> freeze an object? No; it changes the compile-time view and is shallow.
  4. How rename keys? Use the as clause in a mapped type.
  5. When avoid complex mapped types? When the transformed contract is hard to understand or runtime shape differs.

References