Mapped Type Basics

Looping Over Keys

A mapped type { [K in Keys]: Type } creates an object type with one property per key. Combined with keyof T, it transforms every property of an existing type.

Example

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

type Flags<T> = { [K in keyof T]: boolean };
type Getters<T> = { [K in keyof T]: () => T[K] };

const dirty: Flags<Product> = { id: false, name: true, price: true };

const product: Product = { id: 1, name: "Kettle", price: 1299 };
const getters: Getters<Product> = {
  id: () => product.id,
  name: () => product.name,
  price: () => product.price,
};

const changed = (Object.keys(dirty) as (keyof Product)[]).filter((k) => dirty[k]);
console.log("changed fields:", changed);
console.log(getters.price() + 1);

Output

changed fields: [ 'name', 'price' ]
1300

Mapping Over a Union of Literals

Example

The keys do not have to come from keyof; any union of string literals works. (This is what Record does.)

type Locale = "en" | "hi" | "te";
type Translations = { [L in Locale]: string };

const addToCart: Translations = {
  en: "Add to cart",
  hi: "कार्ट में डालें",
  te: "కార్ట్‌కు జోడించండి",
};
const lang: Locale = "hi";
console.log(addToCart[lang]);

Output

कार्ट में डालें