TypeScript ยท Chapter 36 of 44

TypeScript Mapped Types

Mapped types let you create a new type by transforming every property of an existing type using a consistent rule, similar to how array methods like map() transform every element.

Mapped types are the mechanism behind built-in utility types like Partial and Readonly. You can also write your own mapped types for custom transformations not covered by the built-in ones.

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

Basic mapped type syntax

A mapped type looks like `{ [K in keyof T]: T[K] }`, which iterates over every key K in T and keeps the same type for each property, forming an identical copy of T.

Adding modifiers

You can add `readonly` or `?` in a mapped type to transform every property, such as `{ readonly [K in keyof T]: T[K] }`, which is essentially how the built-in Readonly<T> works.

Example 1 (typescript)
interface User {
  name: string;
  age: number;
}
type ReadonlyUser = {
  readonly [K in keyof User]: User[K];
};
const u: ReadonlyUser = { name: "Sam", age: 22 };
console.log(u.name);
Output
Sam

The mapped type makes every property of User readonly by iterating over its keys.

Example 2 (typescript)
interface User {
  name: string;
  age: number;
}
type OptionalUser = {
  [K in keyof User]?: User[K];
};
const partialUser: OptionalUser = { name: "Kim" };
console.log(partialUser);
Output
{ name: 'Kim' }

Adding `?` in the mapped type makes every property optional, similar to the built-in Partial<T>.

Key points

  • Mapped types transform every property of an existing type using one rule.
  • They use the syntax `[K in keyof T]` to iterate over property keys.
  • Modifiers like readonly and ? can be added during mapping.
  • Built-in utility types like Partial and Readonly are implemented using mapped types.
๐Ÿ’ก Note: Understanding mapped types helps you read and even build your own custom utility types.

๐Ÿ“ Quick Quiz

1. What does a mapped type iterate over?

2. Which built-in utility types are implemented using mapped types?

3. What syntax is used to iterate over keys in a mapped type?