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.T
represents the original type.P
represents each property in the original type.keyof T
produces a union type of all keys inT
.in
is a keyword that denotes the mapping process.NewType
is 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)