Use for questions about types for transforming other types, aka mapped types, in TypeScript, either custom or included in the standard library (like Omit, Partial, Pick, Readonly).
Use for questions about TypeScript's mapped types alongside the typescript tag.
Mapped types are generic utility types allowing powerful type transformations while reducing code bloat, for example:
type Inverse<T extends (...args: any[]) => any> = (arg: ReturnType<T>) => Parameters<T>;
type pt = Inverse<(x: string) => number>; //(arg: number) => [x: string];
Mapped types can also modify type's properties via mapping modifiers like readonly
(marks as immutable) and ?
(marks as optional) prefixed with +
(add mod) or -
(remove mod) operation (+
is assumed if missing):
type MakeReadonly<T> = {
readonly [ P in keyof T ] : T[P]
}
const r: MakeReadonly<{ a: 42 }> = { a : 42 };
r.a = 0; //Cannot assign to 'a' because it is a read-only property.
Users are free to define their own mapped types, but a set of the most common ones is included in the standard library. Among those are (many more are available, see the handbook):
Alias | Role |
---|---|
Exclude<T, U> |
only members of T not assignable to U |
Extract<T, U> |
only members of T assignable to U |
Omit<T, K> |
type with properties whose keys are not of type K |
Partial<T> |
all properties optional |
Pick<T, K> |
type with properties whose keys are of type K |
Readonly<T> |
all properties immutable |
Record<K, T> |
type with keys of type K and values of T |
Required<T> |
all properties required |
v4.1 of TypeScript introduced key remapping that allows one to modify keys alongside values and optionally filter out properties if the as
clause resolves to never
:
type OnlyNumeric<T> = {
[ P in keyof T as T[P] extends number ? P : never ] : T[P]
};
type num = OnlyNumeric<{ a: 1, b: "str", c: false }>; //{ a: 1 }
Useful Q&As: