How to Use Mapped Types in TypeScript
Use mapped types in TypeScript when you need to transform every property of an existing object type in a consistent way. They are perfect for update payloads, readonly models, nullable transforms, and reusable library utilities.
What you’ll build or solve
You’ll learn how to use mapped types in TypeScript to transform object properties with keyof, modifiers, and custom value rules. You’ll also know when mapped types are cleaner than rewriting shapes manually.
Learn TypeScript on Mimo
When this approach works best
This approach is the right choice when multiple properties should follow the same type rule.
Common real-world scenarios include:
- Partial update payloads
- Readonly configs
- Nullable form states
- API response transforms
- Feature flag models
This is a bad idea when the target type is tiny and rewriting it manually is clearer.
Prerequisites
You only need:
- Strong TypeScript object type knowledge
keyof- Generics
- Utility type familiarity
Step-by-step instructions
Step 1: Create a basic mapped type
The core syntax loops over keys.
type Stringify<T> = {
[K in keyof T]: string;
};
This converts every property value into string.
type User = {
id: number;
active: boolean;
};
type UserStrings = Stringify<User>;
The result becomes:
{
id: string;
active: string;
}
Step 2: Make every property optional
Mapped types are great for update payloads.
type Optional<T> = {
[K in keyof T]?: T[K];
};
This works like the built-in Partial<T>.
It is ideal for patch APIs and forms.
Step 3: Make every property readonly
Use readonly modifiers.
type ReadonlyFields<T> = {
readonly [K in keyof T]: T[K];
};
This protects configuration objects and immutable state.
Step 4: Combine custom transforms
Mapped types can transform values too.
type Nullable<T> = {
[K in keyof T]: T[K] | null;
};
This is excellent for form-reset states.
What to look for:
- Use
[K in keyof T] - Great for property-wide transforms
- Add
?for optional fields - Add
readonlyfor immutability - Great for reusable object utilities
Examples you can copy
Optional update payload
type Patch<T> = {
[K in keyof T]?: T[K];
};
Readonly config
type Frozen<T> = {
readonly [K in keyof T]: T[K];
};
Nullable form
type Resettable<T> = {
[K in keyof T]: T[K] | null;
};
Common mistakes and how to fix them
Mistake 1: Using mapped types for tiny one-off objects
What the reader might do:
Create a generic mapped helper for a 2-field local object.
Why it breaks: the abstraction adds noise.
Corrected approach:
Write the object shape directly.
Mistake 2: Forgetting to preserve original property values
What the reader might do:
[K in keyof T]: string
when the original type should remain.
Why it breaks: values lose original typing.
Corrected approach:
Use T[K] when preserving the type.
Mistake 3: Over-nesting mapped utilities
What the reader might do:
Layer many transforms into one unreadable helper.
Why it breaks: maintenance suffers.
Corrected approach:
Compose smaller named mapped types.
Troubleshooting
If values lose their original type, use T[K].
If updates need optional fields, add ?.
If state must stay immutable, add readonly.
If the utility becomes unreadable, split it.
Quick recap
- Use
[K in keyof T]for mapped types - Great for object-wide transforms
- Add
?for optional properties - Add
readonlyfor immutable models - Keep helpers small and reusable
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot