type Optional<T> = { [K in keyof T]?: T[K] };
type Mutable<T> = { -readonly [K in keyof T]: T[K] };
type Concrete<T> = { [K in keyof T]-?: T[K] };
type NoId<T> = { [K in keyof T as Exclude<K, "id">]: T[K] };
A mapped type builds a new object type by looping over a union of keys, usually keyof T. The syntax is [K in Keys]: .... Most object utility types, such as Partial, Readonly and Pick, are mapped types.
You can add modifiers to each property:
?makes each property optional.readonlymakes each property readonly.
A - prefix removes a modifier:
-readonlymakes properties writable.-?makes properties required.
A + prefix also exists, but adding is already the default.
The as clause (added in TypeScript 4.1) changes the keys. This is called key remapping. You can:
- rename keys, often with template literal types, like turning
nameintogetName - remove keys by mapping a key to
never, asNoIddoes
- A mapped type loops over keys:
[K in keyof T]: T[K]. - Add
?orreadonlyto properties, and remove them with-?or-readonly. - The
asclause renames keys. - Mapping a key to
neverremoves it from the result.
Read more