Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Динамічні ключі об'єкта». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Об'єкт із динамічними ключами описують через **індексну сигнатуру** (`[key: string]: string`) або через узагальнений тип **`Record<K, T>`**, який означає «об'єкт, де кожен ключ має тип `K`, а значення - тип `T`». **Ключове:** індексна сигнатура допускає будь-які ключі одного типу, а `Record` дає змогу строго обмежити набір ключів, тому вибір залежить від того, чи потрібно фіксувати конкретні ключі, чи ні.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## 1. Використати **індексну сигнатуру** (`index signature`) Це найбазовіший і найпоширеніший спосіб. ```javascript interface Dictionary { [key: string]: string; } const colors: Dictionary = { red: "#ff0000", green: "#00ff00", blue: "#0000ff", }; ``` > Тут `[key: string]: string` означає: > об'єкт може мати **будь-яку кількість властивостей** із ключами типу `string`, > і **всі значення** мають бути рядками. --- ### Варіанти індексних сигнатур | Сигнатура | Що означає | |---|---| | `[key: string]: string` | ключі - рядки, значення - рядки | | `[key: number]: boolean` | ключі - числа, значення - булеві | | `[key: string]: any` | ключі - будь-які рядки, значення - будь-якого типу | | `[key: string]: SomeType` | значення відповідають користувацькому типу | --- ### Приклад з користувацьким типом ```javascript interface UserScores { [username: string]: number; } const scores: UserScores = { Tim: 90, Max: 75, John: 82, }; ``` > TypeScript перевірить, що всі значення - числа. --- ## 2. Використати **узагальнений тип (generic)** з `Record` TypeScript надає утилітний тип `Record<K, T>` - зручний спосіб описати об'єкти з динамічними ключами певного типу. ```javascript type Dictionary = Record<string, string>; const translations: Dictionary = { hello: "Hola", bye: "Adios", }; ``` > `Record<K, T>` буквально означає: > "об'єкт, де кожен ключ має тип `K`, а значення - тип `T`". --- ### Приклад: типізовані ключі ```javascript type Languages = "en" | "fr" | "de"; type LocaleMap = Record<Languages, string>; const appName: LocaleMap = { en: "Shop", fr: "Boutique", de: "Geschaft", }; ``` > TypeScript гарантує, що будуть **усі три ключі** (`en`, `fr`, `de`), > і що **інших бути не може**. --- ## 3. Опис об'єкта з динамічними ключами **і додатковими полями** Можна комбінувати конкретні властивості з індексною сигнатурою. ```javascript interface ProductInfo { id: number; name: string; [extraField: string]: string | number; } const product: ProductInfo = { id: 10, name: "Shirt", color: "white", price: 49, }; ``` > TypeScript дозволяє додавати будь-які поля, > але значення повинні бути **string або number** (за індексною сигнатурою). --- ## 4. Динамічні ключі, обчислені з типу TypeScript вміє створювати об'єкти з ключами, виведеними **з union-типу**: ```javascript type Status = "loading" | "success" | "error"; type StatusMessages = { [K in Status]: string; }; const messages: StatusMessages = { loading: "Loading...", success: "Success!", error: "Error!", }; ``` > Тут використовується **mapped type** - > TypeScript генерує об'єкт із ключами `"loading" | "success" | "error"` > і значеннями типу `string`. --- ## 5. Якщо потрібні **часткові (необов'язкові)** динамічні ключі Можна додати `Partial<>`: ```javascript type FeatureFlags = Partial<Record<"darkMode" | "beta" | "ads", boolean>>; const flags: FeatureFlags = { darkMode: true, // можна // інші ключі можна не вказувати }; ``` --- ## 6. Різниця між `Record` і індексною сигнатурою | Властивість | `Record` | Індексна сигнатура | |---|---|---| | Ключі строго типізовані | Так | Ні (будь-які рядки) | | Можна обмежити конкретними ключами | Так | Ні | | Можна комбінувати з конкретними властивостями | Складніше | Легко | | Зручний для "словникових/enum" структур | Так | Іноді | --- ## 7. Приклад із реального життя ### Словник перекладів ```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" }, }; ``` --- ## Підсумок > У TypeScript об'єкт з динамічними ключами можна описати кількома способами: | Сценарій | Рішення | Приклад | |---|---|---| | Будь-які ключі і значення | **Індексна сигнатура** | `[key: string]: string` | | Ключі обмежені типом | **Record<K, T>** | `Record<"en" | ... >` | | Ключі формуються з union-типу | **Mapped Type** | `[K in Status]: string` | | Усі поля опціональні | **Partial + Record** | `Partial<Record<K, T>>` |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.