Mapped types
Build types from other types.
A mapped type walks the keys of an existing type and produces a new one β the machinery behind Partial, Readonly, and Record, and the place to reach when no built-in utility fits.
The mapping syntax
A mapped type has the shape { [K in Keys]: ValueType }. K is a fresh type variable bound to each member of the union Keys in turn β almost always keyof T. Inside the body you can reference K (the current key) and T[K] (the value type at that key). This single construct is how the standard library defines Partial, Readonly, Pick, and Record.
Modifiers: readonly and ?
Each mapped property can carry the readonly and optional (?) modifiers, and you control them with + (add) or - (remove). { readonly [K in keyof T]: T[K] } adds readonly; { -readonly [K in keyof T]: T[K] } strips it. The same applies to ?: [K in keyof T]? makes everything optional, [K in keyof T]-? makes everything required. A bare readonly/? is shorthand for +readonly/+?.
Key remapping with as
{ [K in keyof T as NewKey]: T[K] } lets you rename keys while you map. Combined with template literal types you can prefix keys (`get${Capitalize<...>}`), and by mapping a key to never you can filter it out entirely β a key that resolves to never is dropped from the result.
Mapping over a union of keys
The source of keys need not be keyof T. Map over any string-literal union and you get a Record-like object whose keys are fixed at the type level, with a uniform β or even key-dependent β value type.
Try it 5 examples
Readonly<T> by hand
TSintroThe output keys: x,y / values: 3 shows the data survives the mapping intact β MyReadonly<T> only adds the readonly modifier, it never touches the runtime shape or values. The compile-time guard (assigning p.x would error) is invisible at runtime, which is exactly why mapped types cost nothing.