Understanding TypeScript 2.0's Mapped Types
Published on June 24, 2020
Introduction
In this post, we will delve into TypeScript 2.0’s mapped types and explore how they can be used to simplify complex type definitions in your codebase. We will start with the basics and then move on to more advanced topics…
Mapped Types
Mapped types are a powerful feature of TypeScript that allow you to map one type onto another. They are particularly useful when you want to reuse a type definition across multiple places in your codebase.
For example, let’s say you have a User
interface with several properties:
interface User {
id: number;
name: string;
email: string;
}
If you want to define a User
object with a specific set of properties, you can use a mapped type like this:
type UserWithEmail = {
[K in keyof User]: K extends 'email' ? string : never;
};
This will create a new type called UserWithEmail
that has the same properties as User
, but with an additional email property. The never
keyword is used to indicate that any other properties that are not specified in the mapped type will be excluded from the resulting type.
Mapped types can also be used to create more complex types, such as interfaces or classes, by using a more complex mapping function. For example:
interface UserWithEmail {
id: number;
name: string;
email: string;
}
type UserWithPassword = {
[K in keyof UserWithEmail]: K extends 'password' ? string : never;
};
This will create a new type called UserWithPassword
that has all the properties of UserWithEmail
, plus an additional password property.
Mapped Types with Generics
Mapped types can also be used with generics to create more flexible and reusable type definitions. For example:
interface User<T extends string> {
id: number;
name: T;
}
type UserWithEmail = User<'email'>;
type UserWithPassword = User<'password'>;
This will create two new types called UserWithEmail
and UserWithPassword
, which have the same properties as the User
interface, but with different types for the name property. The 'email'
and 'password'
strings are used to specify the type of the name property in each case.
Mapped types can be combined with other features of TypeScript, such as conditional types, to create even more flexible and powerful type definitions. For example:
type UserWithEmailOrPassword = {
[K in keyof User]: K extends 'email' | 'password' ? string : never;
};
This will create a new type called UserWithEmailOrPassword
that has all the properties of the User
interface, but with an additional email and password property. The never
keyword is used to indicate that any other properties that are not specified in the mapped type will be excluded from the resulting type.
Conclusion
Mapped types are a powerful feature of TypeScript that allow you to simplify complex type definitions in your codebase. They can be used with generics to create more flexible and reusable type definitions, and can be combined with other features of TypeScript to create even more powerful type definitions. By understanding how mapped types work, you can write more robust and maintainable code, and take advantage of the full potential of TypeScript’s type system.