JS Guide
HomeQuestionsTopicsCompaniesResources
BookmarksSearch

Built for developers preparing for JavaScript, React & TypeScript interviews.

ResourcesQuestionsSupport
HomeQuestionsSearchProgress
HomeTopicstypescriptMapped Types
PrevNext
typescript
advanced
10 min read

Mapped Types

advanced
key-remapping
keyof
mapped-types
modifiers
utility-types

Mapped types transform existing types by iterating over their keys with { [K in keyof T]: NewType } — modifiers add/remove readonly and optional, key remapping (as clause) filters or renames keys, and they power built-in utilities like Partial, Required, Readonly, and Record.

Key Points

1Property Iteration

{ [K in keyof T]: T[K] } iterates over every property of T — the foundation for transforming existing types into new ones.

2Modifiers

Add readonly or ? with + (default), remove with -. Required<T> uses -? to make all properties required; Mutable uses -readonly.

3Key Remapping (as)

Filter keys by mapping to never, rename with template literals, or compute new keys — enables patterns like Getters<T> and property filtering.

4Built-in Utilities

Partial, Required, Readonly, Pick, Omit, and Record are all mapped types — understanding the pattern helps extend and debug them.

What You'll Learn

  • Write mapped types that transform existing type properties
  • Use modifiers (+/- readonly and ?) to control property attributes
  • Apply key remapping with the as clause for filtering and renaming
  • Explain how built-in utility types (Partial, Required, Pick) are implemented

Deep Dive

Mapped types create new types by transforming every property of an existing type. They're TypeScript's equivalent of Array.map() but for type-level properties.

Basic Syntax

A mapped type iterates over keys and produces a new type for each:

TSX
type Readonly<T> = { readonly [K in keyof T]: T[K] };
  • keyof T produces a union of T's property names
  • K in iterates over each key in the union
  • T[K] is an indexed access type — the type of property K on T
  • The result has the same keys as T but with readonly added

Property Modifiers

Mapped types can add or remove readonly and ? (optional) modifiers:

TSX
// Add readonly to all properties
type Readonly<T> = { readonly [K in keyof T]: T[K] };
 
// Make all properties optional
type Partial<T> = { [K in keyof T]?: T[K] };
 
// Remove optional (make all required)
type Required<T> = { [K in keyof T]-?: T[K] };
 
// Remove readonly
type Mutable<T> = { -readonly [K in keyof T]: T[K] };

The - prefix removes a modifier, + adds it (the default). Required<T> uses -? to strip optional markers from every property.

Key Remapping with as

TypeScript 4.1 added key remapping to filter, rename, or compute new keys:

TSX
// Filter: keep only string-valued properties
type StringProps<T> = {
  [K in keyof T as T[K] extends string ? K : never]: T[K]
};
 
// Rename: prefix all keys with 'get'
type Getters<T> = {
  [K in keyof T as `get${Capitalize<string & K>}`]: () => T[K]
};

Mapping a key to never removes it from the result — this is how you implement filtering. Template literal types in the as clause enable dynamic key renaming.

Built-in Mapped Utility Types

TypeScript's standard library includes several mapped types:

  • Partial<T> — all properties optional
  • Required<T> — all properties required
  • Readonly<T> — all properties readonly
  • Record<K, V> — object with keys K and values V: { [P in K]: V }
  • Pick<T, K> — select subset of properties: { [P in K]: T[P] }
  • Omit<T, K> — remove properties (implemented as Pick<T, Exclude<keyof T, K>>)

Understanding that these are mapped types helps debug and extend them.

Mapping Over Unions

You can map over any union, not just keyof T:

TypeScript
type EventHandlers = {
  [K in 'click' | 'focus' | 'blur']: (event: Event) => void
};

Record<K, V> is the built-in version of this pattern.

Recursive Mapped Types

Combine mapped types with conditional types for deep transformations:

TSX
type DeepReadonly<T> = {
  readonly [K in keyof T]: T[K] extends object ? DeepReadonly<T[K]> : T[K]
};

This recursively makes every nested property readonly — useful for immutable state patterns.

Preserving Modifiers

By default, mapped types preserve the optional and readonly modifiers of the original type. If the original property is optional, the mapped property is optional too (unless you explicitly change it with -? or -readonly).

Key Interview Distinction

Mapped types iterate over keys with [K in keyof T] to create new types — they're the mechanism behind Partial, Required, Readonly, Pick, and Record. Modifiers (+/- readonly and ?) control property attributes. Key remapping (as clause) enables filtering (map to never) and renaming (template literal types). Recursive mapped types with conditional types enable deep transformations.

Fun Fact

Key remapping (the as clause in mapped types) was one of the most requested TypeScript features for years before it landed in TypeScript 4.1. Before key remapping, filtering properties required a two-step pattern combining Pick and conditional types — now it's a single expression.

Learn These First

Generics

intermediate

Interfaces vs Type Aliases

beginner

Continue Learning

Conditional Types

advanced

Utility Types

intermediate

Template Literal Types

advanced

Practice What You Learned

How do mapped types work in TypeScript?
senior
mapped-types
Mapped types transform existing types by iterating over their keys using 'in keyof' syntax. They can modify properties (make optional, readonly), rename keys, and filter properties. Built-in utilities like Partial, Required, and Pick use mapped types.
Previous
Interfaces vs Type Aliases
Next
Module System
PrevNext