Suggest an editImprove this articleRefine the answer for “Dynamic object keys”. Your changes go to moderation before they’re published.Approval requiredContentWhat you’re changing🇺🇸EN🇺🇦UAPreviewTitle (EN)Short answer (EN)An object with dynamic keys is described using an **index signature** (`[key: string]: string`) or the generic utility type **`Record<K, T>`**, which literally means "an object where each key has type `K` and the value has type `T`". **Key point:** an index signature allows any keys of one type, while `Record` lets you strictly restrict the set of keys, so the choice depends on whether specific keys need to be fixed or not.Shown above the full answer for quick recall.Answer (EN)Image## 1. Use an **index signature** This is the most basic and common way. ```javascript interface Dictionary { [key: string]: string; } const colors: Dictionary = { red: "#ff0000", green: "#00ff00", blue: "#0000ff", }; ``` > Here `[key: string]: string` means: > the object can have **any number of properties** with keys of type `string`, > and **all the values** must be strings. --- ### Variants of index signatures | Signature | What it means | |---|---| | `[key: string]: string` | keys are strings, values are strings | | `[key: number]: boolean` | keys are numbers, values are booleans | | `[key: string]: any` | keys are any strings, values are of any type | | `[key: string]: SomeType` | values match a custom type | --- ### An example with a custom type ```javascript interface UserScores { [username: string]: number; } const scores: UserScores = { Tim: 90, Max: 75, John: 82, }; ``` > TypeScript checks that all the values are numbers. --- ## 2. Use a **generic type** with `Record` TypeScript provides the utility type `Record<K, T>` - a convenient way to describe objects with dynamic keys of a certain type. ```javascript type Dictionary = Record<string, string>; const translations: Dictionary = { hello: "Hola", bye: "Adios", }; ``` > `Record<K, T>` literally means: > "an object where each key has type `K` and the value has type `T`". --- ### Example: typed keys ```javascript type Languages = "en" | "fr" | "de"; type LocaleMap = Record<Languages, string>; const appName: LocaleMap = { en: "Shop", fr: "Boutique", de: "Geschaft", }; ``` > TypeScript guarantees that **all three keys** (`en`, `fr`, `de`) are present, > and that **no others can be**. --- ## 3. Describing an object with dynamic keys **plus extra fields** You can combine specific properties with an index signature. ```javascript interface ProductInfo { id: number; name: string; [extraField: string]: string | number; } const product: ProductInfo = { id: 10, name: "Shirt", color: "white", price: 49, }; ``` > TypeScript lets you add any fields, > but the values must be **string or number** (per the index signature). --- ## 4. Dynamic keys computed from a type TypeScript can build objects with keys derived **from a union type**: ```javascript type Status = "loading" | "success" | "error"; type StatusMessages = { [K in Status]: string; }; const messages: StatusMessages = { loading: "Loading...", success: "Success!", error: "Error!", }; ``` > This uses a **mapped type** - > TypeScript generates an object with keys `"loading" | "success" | "error"` > and values of type `string`. --- ## 5. If you need **partial (optional)** dynamic keys You can add `Partial<>`: ```javascript type FeatureFlags = Partial<Record<"darkMode" | "beta" | "ads", boolean>>; const flags: FeatureFlags = { darkMode: true, // allowed // other keys can be left out }; ``` --- ## 6. The difference between `Record` and an index signature | Property | `Record` | Index signature | |---|---|---| | Keys are strictly typed | Yes | No (any strings) | | Can be restricted to specific keys | Yes | No | | Can be combined with specific properties | Harder | Easy | | Convenient for "dictionary/enum" structures | Yes | Sometimes | --- ## 7. A real-life example ### A translation dictionary ```javascript type Locale = "en" | "fr" | "de"; interface Translations { [key: string]: Record<Locale, string>; } const ui: Translations = { login: { en: "Login", fr: "Connexion", de: "Anmelden" }, logout: { en: "Logout", fr: "Deconnexion", de: "Abmelden" }, }; ``` --- ## Summary > In TypeScript, an object with dynamic keys can be described in several ways: | Scenario | Solution | Example | |---|---|---| | Any keys and values | **Index signature** | `[key: string]: string` | | Keys restricted by type | **Record<K, T>** | `Record<"en" | ... >` | | Keys derived from a union type | **Mapped Type** | `[K in Status]: string` | | All fields optional | **Partial + Record** | `Partial<Record<K, T>>` |For the reviewerNote to the moderator (optional)Visible only to the moderator. Helps review go faster.