DevAcademy
LearnTypeScriptMapped Types
AdvancedTypeScript

Mapped Types

Learn how to transform every property of an existing type into a new type using mapped type syntax.

Reading Time

18 min

Lesson

Lesson 23 of 30

What is a Mapped Type?

A mapped type builds a new type by iterating over the keys of an existing type (or a union of literal keys) and applying the same transformation to each one — it’s essentially a "map()" for types.

A Basic Mapped Type

type User = {
  name: string;
  email: string;
};

type ReadonlyUser = {
  readonly [K in keyof User]: User[K];
};

// Equivalent to: { readonly name: string; readonly email: string }

This is How Partial and Readonly Are Built

TypeScript’s own built-in Partial<T> and Readonly<T> utility types are just mapped types under the hood.

Reimplementing Partial

type MyPartial<T> = {
  [K in keyof T]?: T[K];
};

type PartialUser = MyPartial<User>;
// { name?: string; email?: string }

Modifiers: Adding and Removing ? and readonly

A - prefix removes a modifier instead of adding it, letting a mapped type strip optionality or readonly from an existing type.

Removing Modifiers

type PartialUser = { name?: string; email?: string };

// Strips '?' from every property, making them all required again
type RequiredAgain = {
  [K in keyof PartialUser]-?: PartialUser[K];
};

Remapping Keys with as

A mapped type can rename each key as it maps over them, using the as clause — useful for building things like a set of getter method names from a plain object type.

Key Remapping

type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K];
};

type UserGetters = Getters<User>;
// { getName: () => string; getEmail: () => string }

Mapping Over a Union of Literals

Mapped types don’t need to start from keyof — they can iterate over any union of string literals directly.

Mapping Over a Literal Union

type Role = "admin" | "editor" | "viewer";

type RolePermissions = {
  [R in Role]: boolean;
};
// { admin: boolean; editor: boolean; viewer: boolean }

Best Practice

You rarely need to write mapped types from scratch — reach for the built-in utility types first, and write a custom mapped type only when nothing built-in expresses the exact transformation you need.

Interview Questions

Quick Quiz

1. What does a mapped type do, conceptually?

2. What does the -? modifier do inside a mapped type?

3. What does the as clause inside a mapped type allow?