What Are Mapped Types? 🤔
Mapped types are a way to create new types by transforming the properties of an existing type. Essentially, they allow you to iterate over the properties of one type and create a new type based on those properties. This can be incredibly useful for scenarios like creating read-only or optional versions of types or filtering out specific properties.
Basic Syntax 📝
type MappedType<T> = { [P in keyof T]: NewType; }; Here's a breakdown of what each part means:
{}: Encloses the mapped type definition.Trepresents the original type.Prepresents each property in the original type.keyof Tproduces a union type of all keys inT.inis a keyword that denotes the mapping process.NewTypeis the type you want to assign to each property in the new type.
Creating a Read-Only Type 🔒
One common use case for mapped types is to create a read-only version of an object type. Let's say we have a type representing a user:
type User = { id: number; name: string; email: string; }; We can create a read-only version of this type using a mapped type:
type ReadOnlyUser = { readonly [K in keyof User]: User[K]; }; In this example, [K in keyof User] iterates over each property in the User type, and User[K] retains the type of each property. The readonly modifier makes each property read-only.
Now, if we try to modify a property of ReadOnlyUser, TypeScript will throw an error:
const user: ReadOnlyUser = { id: 1, name: "Alice", email: "alice@example.com", }; user.name = "Bob"; // Error: Cannot assign to 'name' because it is a read-only property. Creating Optional Properties ❓
Mapped types can also be used to make properties optional. Let's say we have a type representing a configuration:
type AppConfig = { apiKey: string; loggingEnabled: boolean; maxRequestsPerMinute: number; }; We can create a version of this type where all properties are optional like this:
type OptionalConfig = { [K in keyof AppConfig]?: AppConfig[K]; }; Now, all properties in OptionalConfig are optional:
const config: OptionalConfig = { apiKey: "my-api-key", // No need to specify other properties }; Filtering Out Properties 🧹
Mapped types also allow us to filter out specific properties from a type. Let's say we want to create a type that excludes the loggingEnabled property from AppConfig:
type WithoutLogging = { [K in Exclude<keyof AppConfig, "loggingEnabled">]: AppConfig[K]; }; In this example, we use the Exclude utility type to remove the "loggingEnabled" property from the keys of AppConfig. The resulting type, WithoutLogging, does not contain the loggingEnabled property:
const config: WithoutLogging = { apiKey: "my-api-key", maxRequestsPerMinute: 100, };
Top comments (0)