Learn TypeScript
Creating a mapped type
Creating a mapped type
In this lesson, we will learn what mapped types are and how to create them.
Understanding a mapped type
A mapped type is the process of creating a new type by mapping type information from an existing type.
type MappedTypeName = { [K in UnionType]: ExistingType };The in operator maps over each item in the union type to create a new type. In other words, the in operator allows us to loop through each type in a union type. In a loop iteration, wach item in the union type is put in K, which becomes a key in the new type. So, the union type is usually a union of string literals. The type annotation in the mapped type is the type given to each key in the type.
So:
type ContactDetails = { [K in "name" | "email"]: string };... creates the following type:
{ name: string; email: string;}This becomes more useful when used with the keyof operator we learned about in the last lesson:
type MappedTypeName = { [K in keyof ExistingType1]: ExistingType2;};This creates a new type containing the keys from another type.
An example
We are going to explore a useful example of a mapped type in the code editor below:
The editor contains a generic Form interface and a contactForm variable that uses this interface for its type.
Can you spot a problem with the object assigned to contactForm?
Why doesn't a type error occur to surface this problem?
- Update the
errorstype within theForminterface to use a mapped type based onT:
interface Form<T> { ... errors: { [K in keyof T]: string };}- A type error is now raised on
emailAddress, which a great. So, change this toemail.
A type error still exists on errors. What is the problem?
- The problem can be resolved if we make the mapped keys optional in the errors type. Update the mapped type so that its keys are optional by placing a question mark (
?) in front of the key's type annotation.
All the type errors are now resolved.
Great!
- Add another property in the type passed into
Form:
const contactForm: Form<{ ... mobile: string;}> = { ...};- Add a mobile number in the
valuesobject:
values: { ... mobile: "0745 6723432"},- Add an error for
mobilein theerrorsobject. Type this out manually and notice the intellisense.
errors: { ... mobile: "You must add a mobile number"},Notice that no type errors are raised.
Nice!
Summary
Mapped types allow us to create new types based on an existing type. They are useful for handling generic data in a strongly-typed manner.
In the next lesson, we will learn about using type modifiers in mapped types.
