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.


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:

TypeScriptOpen exercise in CodeSandbox

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 errors type within the Form interface to use a mapped type based on T:
interface Form<T> {
errors: { [K in keyof T]: string };
  • A type error is now raised on emailAddress, which a great. So, change this to email.

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.


  • Add another property in the type passed into Form:
const contactForm: Form<{
mobile: string;
}> = {
  • Add a mobile number in the values object:
values: {
mobile: "0745 6723432"
  • Add an error for mobile in the errors object. Type this out manually and notice the intellisense.
errors: {
mobile: "You must add a mobile number"

Notice that no type errors are raised.



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.

© 2020 Carl Rippon
Privacy Policy
This site uses cookies. Click here to find out more