🔁 TypeScript – Mapped Types: A Complete Guide with Real-World Examples

🧲 Introduction – What Are Mapped Types in TypeScript?

In TypeScript, Mapped Types are a powerful and expressive feature that let you create new types by transforming properties from existing ones. With mapped types, you can add, remove, or change the modifiers (readonly, optional, etc.) of object properties in a reusable, scalable way.

🎯 In this guide, you’ll learn:

  • What mapped types are and how they work
  • Syntax and real-world applications
  • How to combine them with utility types and conditional types
  • Practical examples for UI state, forms, APIs, and more

📘 What Are Mapped Types?

Mapped types allow you to iterate over the keys of a type and apply transformations to each property using keyof and in.

📌 Basic Syntax:

type NewType = {
  [Key in keyof OriginalType]: Transformation;
};
  • keyof OriginalType gets all property keys.
  • Key in ... loops through each key.
  • Transformation is applied to each property’s type.

🧪 Example 1: Basic Mapped Type

type User = {
  name: string;
  age: number;
};

type StringifiedUser = {
  [K in keyof User]: string;
};

🔍 Explanation:

  • We loop through keys "name" and "age".
  • We assign string as the new type for all keys.

✅ Result:

// Equivalent to:
type StringifiedUser = {
  name: string;
  age: string;
};

🔐 Example 2: Making All Properties Optional

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

type Post = {
  title: string;
  body: string;
};

type DraftPost = Optional<Post>;

🔍 Explanation:

  • ? makes each property optional.
  • Result: { title?: string; body?: string; }

✅ This is how TypeScript’s built-in Partial<T> utility type works.


🔒 Example 3: Making All Properties Readonly

type ReadonlyProps<T> = {
  readonly [K in keyof T]: T[K];
};

type Settings = {
  theme: string;
  notifications: boolean;
};

type FrozenSettings = ReadonlyProps<Settings>;

🔍 Explanation:

  • readonly prevents future changes to values.
  • Now, FrozenSettings properties cannot be reassigned.

🔄 Example 4: Removing Optional or Readonly Modifiers

You can remove modifiers using -? or -readonly.

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

type Mutable<T> = {
  -readonly [K in keyof T]: T[K];
};

📌 These mimic TypeScript’s built-in Required<T> and Mutable<T> (from libraries like utility-types).


💡 Example 5: Combining with Conditional Types

type BooleanMap<T> = {
  [K in keyof T]: T[K] extends boolean ? "toggle" : "input";
};

type FormControls = {
  subscribe: boolean;
  email: string;
};

type ControlTypes = BooleanMap<FormControls>;

🔍 Output:

// ControlTypes becomes:
{
  subscribe: "toggle";
  email: "input";
}

🧠 Use cases: dynamically rendering form elements or UI controls based on property types.


🧬 Example 6: Remapping Keys with as

You can rename keys using as (introduced in TypeScript 4.1+):

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

type Product = {
  id: number;
  name: string;
};

type ProductGetters = Getters<Product>;

🔍 Output:

{
  getId: () => number;
  getName: () => string;
}

📌 This is highly useful for generating dynamic method names in APIs or UI frameworks.


🧰 Common Use Cases for Mapped Types

Use CaseExample
Make fields optionalPartial<T>
Make fields requiredRequired<T>
Readonly object configReadonly<T>
Rename fields dynamicallyUsing as in mapped types
Conditional field transformationCombining with T[K] extends U ? ...
Create DTOs or API modelsConvert client types for backend

📌 Summary – Recap & Real-World Relevance

Mapped types in TypeScript are essential for writing clean, scalable, and reusable code. They empower you to construct new types from existing ones with minimal repetition and maximum control.

🔍 Key Takeaways:

  • Use keyof + in to iterate over object properties.
  • Apply modifiers like readonly, optional, or remove them using -?, -readonly.
  • Combine with conditional types for dynamic logic.
  • Use as to rename keys programmatically.

⚙️ Real-world applications:

  • Form builders & dynamic UI
  • Redux state transformations
  • API request/response shape mapping
  • Component prop filtering and auto-generation

❓ FAQs

❓ What are mapped types?

✅ Mapped types allow you to create new types by looping over keys in an existing object type and transforming their values or modifiers.


❓ How are mapped types different from interfaces?

Mapped types are dynamic and can generate new types based on logic, whereas interfaces are static declarations of shape.


❓ Can mapped types work with union types?

Not directly. Mapped types work on object types. To use with unions, you typically combine with conditional types or Extract<T, U>.


❓ Are mapped types used in utility types?

Yes. Built-in types like Partial<T>, Required<T>, Readonly<T>, and even Pick<T, K> internally use mapped type syntax.


Share Now :

Leave a Reply

Your email address will not be published. Required fields are marked *

Share

TypeScript — Mapped Types

Or Copy Link

CONTENTS
Scroll to Top