← Back to TypeScript Course | Chapter 8: Advanced Types | Lesson 2 of 20

Mapped Types

Mapped types create new object types by transforming the properties of an existing type. They are useful when many properties need the same type transformation.

Basic Mapped Type

A mapped type can iterate over the keys of another type and assign a new type to each corresponding property, producing an entirely new object type derived mechanically from an existing one.

Example: Basic Mapped Type

typescript
interface Person {
  name: string;
  age: number;
}
type Flags<T> = { [K in keyof T]: boolean };
const flags: Flags<Person> = { name: true, age: false };
console.log(flags);

Readonly Mapped Types

A mapped type can add readonly to every property of an existing type at once, which is effectively how TypeScript's own built-in Readonly<T> utility type is implemented under the hood.

Example: Readonly Mapped Types

typescript
interface Person {
  name: string;
  age: number;
}
type MyReadonly<T> = { readonly [K in keyof T]: T[K] };
const p: MyReadonly<Person> = { name: "Ravi", age: 25 };
console.log(p);

Changing Property Types

Mapped types can transform every property's value into a related type — for example turning every property of T into T[K] | undefined, or wrapping each one in a Promise.

Example: Changing Property Types

typescript
interface Person {
  name: string;
  age: number;
}
type Nullable<T> = { [K in keyof T]: T[K] | undefined };
const p: Nullable<Person> = { name: "Ravi", age: undefined };
console.log(p);

Using keyof in Mapped Types

The keyof operator obtains the keys of a type, which a mapped type can then iterate over with [K in keyof T], tying the new type's shape directly to the original type's own property names.

Example: Using keyof in Mapped Types

typescript
interface Person {
  name: string;
  age: number;
}
type Stringify<T> = { [K in keyof T]: string };
const p: Stringify<Person> = { name: "Ravi", age: "25" };
console.log(p);

Practical Mapped Types

Mapped types are useful for creating reusable variations of domain models — like an editable or nullable version of a base type — without manually rewriting every property by hand.

Example: Practical Mapped Types

typescript
interface User {
  id: number;
  email: string;
}
type Editable<T> = { [K in keyof T]?: T[K] };
const patch: Editable<User> = { email: "[email protected]" };
console.log(patch);

Login to run this code

C/C++/Java/PHP execution requires a free account. Your code is saved — you'll land right back in the editor after logging in.