Syntax
{ [K in keyof T]: NewValueType }Examples
A Custom Mapped Type
Building a type that makes every property optional - a simplified Partial<T>.
type MyPartial<T> = {
[K in keyof T]?: T[K];
};
interface User {
id: number;
name: string;
}
type PartialUser = MyPartial<User>;
// Equivalent to: { id?: number; name?: string }Mapped Type Modifiers
Adding or removing readonly and optional (?) modifiers, and transforming value types.
type ReadonlyVersion<T> = {
readonly [K in keyof T]: T[K];
};
type RemoveReadonly<T> = {
-readonly [K in keyof T]: T[K]; // the "-" removes the modifier instead of adding it
};
type Stringify<T> = {
[K in keyof T]: string; // transforms every property's VALUE type to string
};
interface Product { id: number; inStock: boolean; }
type StringProduct = Stringify<Product>; // { id: string; inStock: string }Best practices
- Use mapped types to systematically transform every property of an existing type, rather than manually retyping each property by hand
- Study TypeScript's built-in Partial, Required, and Readonly utility types - they are all implemented as short, readable mapped types
- Use the -readonly and -? modifier syntax when you specifically need to strip a modifier rather than add one
- Combine mapped types with conditional types (as clauses, key remapping) for advanced transformations, but keep an eye on readability as complexity grows
Runtime & versions
Compiled to JavaScript. Feature availability depends on the language and runtime version used by your project; consult the official reference below.
TypeScript Handbook