Skip to main content

Динамічні ключі об'єкта

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 + RecordPartial<Record<K, T>>

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.