Mapped Types

One common task is to take an existing type and make each of its properties entirely optional.Let’s say we have a `Person:

  1. interface Person {
  2. name: string;
  3. age: number;
  4. location: string;
  5. }

A partial version of it would be:

  1. interface PartialPerson {
  2. name?: string;
  3. age?: number;
  4. location?: string;
  5. }

with Mapped types, PartialPerson can be written as a generalized transformation on the type Person as:

  1. type Partial<T> = {
  2. [P in keyof T]?: T[P];
  3. };
  4. type PartialPerson = Partial<Person>;

Mapped types are produced by taking a union of literal types, and computing a set of properties for a new object type.They’re like list comprehensions in Python, but instead of producing new elements in a list, they produce new properties in a type.

In addition to Partial, Mapped Types can express many useful transformations on types:

  1. // Keep types the same, but make each property to be read-only.
  2. type Readonly<T> = {
  3. readonly [P in keyof T]: T[P];
  4. };
  5. // Same property names, but make the value a promise instead of a concrete one
  6. type Deferred<T> = {
  7. [P in keyof T]: Promise<T[P]>;
  8. };
  9. // Wrap proxies around properties of T
  10. type Proxify<T> = {
  11. [P in keyof T]: { get(): T[P]; set(v: T[P]): void }
  12. };