TypeScript Mapped Types

🔁 TypeScript Mapped Types (Beginner → Advanced)

Mapped Types in TypeScript allow you to create new types by transforming existing types.
They are a core building block of TypeScript’s type system and power many built-in utility types like Partial, Readonly, Pick, etc.


1️⃣ What Are Mapped Types?

A mapped type iterates over the keys of an existing type and creates a new type.

Think of it as a for loop for types.


2️⃣ Basic Syntax ⭐

type NewType<T> = {
[K in keyof T]: T[K];
};
  • keyof T → gets all property keys

  • K → each key

  • T[K] → type of that property


3️⃣ Simple Mapped Type Example

type User = {
name: string;
age: number;
};
type CopyUser = {
[K in keyof User]: User[K];
};

CopyUser is exactly the same as User


4️⃣ Making All Properties Optional (Partial) ⭐

type MyPartial<T> = {
[K in keyof T]?: T[K];
};
type User = {
name: string;
age: number;
};

type OptionalUser = MyPartial<User>;

Equivalent to:

type OptionalUser = {
name?: string;
age?: number;
};

✔ Very common in forms & updates


5️⃣ Making All Properties Required (Required) ⭐

type MyRequired<T> = {
[K in keyof T]-?: T[K];
};
  • -? removes optional modifier


6️⃣ Making Properties Readonly (Readonly) ⭐

type MyReadonly<T> = {
readonly [K in keyof T]: T[K];
};
type User = {
name: string;
};
const u: MyReadonly<User> = { name: “Amit” };
// u.name = “Rahul”; ❌ Error

✔ Prevents accidental mutation


7️⃣ Removing readonly Modifier 🔥

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

✔ Useful when working with immutable libraries


8️⃣ Renaming Keys with as (Key Remapping) ⭐⭐

type User = {
id: number;
name: string;
};
type GetterMethods<T> = {
[K in keyof T as get${Capitalize<string & K>}]: () => T[K];
};

Result:

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

✔ Advanced & powerful
✔ Common in framework internals


9️⃣ Filtering Keys Using Mapped Types ⭐⭐

type RemoveStringProps<T> = {
[K in keyof T as T[K] extends string ? never : K]: T[K];
};
type Data = {
id: number;
name: string;
active: boolean;
};

type Result = RemoveStringProps<Data>;
// { id: number; active: boolean }

✔ Uses never to remove keys


🔟 Mapped Types + Conditional Types ⭐⭐⭐

type Nullable<T> = {
[K in keyof T]: T[K] | null;
};
type User = {
name: string;
age: number;
};
type NullableUser = Nullable<User>;

✔ Very common in API responses


1️⃣1️⃣ Built-in Utility Types (Mapped Types in Action) ⭐⭐⭐

Utility Type What it does
Partial<T> Makes all properties optional
Required<T> Makes all properties required
Readonly<T> Makes all properties readonly
Pick<T, K> Select specific keys
Omit<T, K> Remove specific keys
Record<K, T> Create key-value map

Example

type UserPreview = Pick<User, "name">;

1️⃣2️⃣ Record – Special Mapped Type

type Role = "admin" | "user";

type Permissions = Record<Role, string[]>;

const perms: Permissions = {
admin: [“read”, “write”],
user: [“read”]
};

✔ Extremely common in configs


1️⃣3️⃣ Common Mistakes ❌

  • Forgetting keyof

  • Overcomplicating mapped types

  • Confusing mapped types with interfaces

  • Not using built-in utility types

  • Forgetting -? or -readonly


📌 Interview Questions (Must Prepare)

  1. What is a mapped type?

  2. How does keyof work?

  3. Difference between Partial and Readonly

  4. How to remove readonly or ?

  5. How does key remapping work?

  6. Difference between mapped types and interfaces


✅ Summary

✔ Mapped types transform existing types
✔ Built using keyof and index access
✔ Power most utility types
✔ Can add/remove ? and readonly
✔ Support key renaming & filtering
✔ Essential for advanced TypeScript & interviews

You may also like...