← 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.
Syntax
typescript
type MappedType<T> = {
  [K in keyof T]: T[K];
};

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);
Related Topics
{# common_mistakes/chapter_summary/browser_support: on Hindi pages the view already swaps in the hi_ translation fields (or blanks these out if untranslated), so this renders correctly for both languages without a lang_code check here. #}
Common Mistakes
  1. Writing [K in T] for an object type, when you need [K in keyof T] to iterate its property names.
  2. Expecting a mapped type to add methods or run at runtime, when it only builds a type.
  3. Forgetting T[K] as the value type and using a fixed type, which loses each property's original type.

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.