Mastering TypeScript Mapped Types for Dynamic Object Transformation
Learn how to use TypeScript mapped types to dynamically transform objects, making your code more flexible and type-safe.
TypeScript is a powerful language that builds on JavaScript by adding static types. One of its standout features is mapped types, which allow you to create new types based on existing ones by transforming their properties. This tutorial will guide you through the basics of mapped types and show you practical examples of how to use them for dynamic object transformations.
### What Are Mapped Types?
Mapped types let you create a new type by iterating over the keys of an existing type and applying a transformation to each property. This is especially useful when you want to manipulate object shapes without manually rewriting each property.
Here is the basic syntax of a mapped type:
type Readonly<T> = {
readonly [P in keyof T]: T[P];
};In this example, `Readonly` transforms any type `T` by making all properties read-only.
### Example: Creating a Partial Type
Let's say you want to create a type where all the properties of an object are optional. TypeScript provides `Partial` as a built-in mapped type, but let's create our own version:
type MyPartial<T> = {
[P in keyof T]?: T[P];
};Now you can use `MyPartial` to transform an entire interface:
interface User {
id: number;
name: string;
email: string;
}
const updateUser: MyPartial<User> = {
name: "Alice"
};Here, `updateUser` can have any subset of the `User` properties.
### Dynamic Object Transformation with Mapped Types
Imagine you want to transform all properties of an object to strings. You can do this easily with a mapped type:
type AllStrings<T> = {
[P in keyof T]: string;
};
const user: AllStrings<User> = {
id: "123",
name: "Bob",
email: "bob@example.com"
};This technique is powerful for dynamically adjusting object shapes to match specific use cases.
### Combining Mapped Types with Conditional Types
Mapped types become even more powerful when combined with conditional types. For example, you can create a type that makes only the string properties optional:
type OptionalStrings<T> = {
[P in keyof T]: T[P] extends string ? T[P] | undefined : T[P];
};Using it with `User` interface:
const userUpdate: OptionalStrings<User> = {
id: 1, // number remains required
name: undefined, // string can be undefined
email: "alice@example.com"
};### Summary
Mapped types give TypeScript developers a dynamic, type-safe way to transform object types without repetitive code. Starting from simple transformations like `Readonly` or `Partial`, you can build more complex types with conditionals tailored to your needs. Experiment with them to make your code cleaner and safer!