Mapped Types
Prerequisites: Utility types
A mapped type builds a new type by transforming every property of an
existing one — how Partial, Readonly, and similar utility types
are actually implemented.
type Optional<T> = {
[K in keyof T]?: T[K];
};
interface User {
name: string;
age: number;
}
type OptionalUser = Optional<User>; // { name?: string; age?: number }
keyof T gets a union of all of T's property names; [K in ...]
iterates over them, producing a new property for each.