Увійти Реєстрація
Блог Серії
Кар'єра
Вакансії Компанії
Навчання
Документація Співбесіди Тестування Відео
Екосистема
Пакети Ресурси Проєкти Інструменти Події
Інше
Про нас Реклама

Що робить оператор keyof?

keyof T - тип-об'єднання всіх ключів типу T:

interface User {
  id: number;
  name: string;
  email: string;
}

type UserKey = keyof User;   // 'id' | 'name' | 'email'

Головне застосування - функції, що працюють з ключами об'єкта безпечно:

function getField<T, K extends keyof T>(obj: T, key: K): T[K] {
  return obj[key];
}

const user: User = { id: 1, name: 'Оля', email: 'olia@example.com' };

getField(user, 'name');    // string
getField(user, 'id');      // number
getField(user, 'phone');   // помилка: 'phone' немає в keyof User

Тип повернення T[K] точно відповідає переданому ключу - не string | number, а саме тип цього поля.

Інші застосування:

  • сортування й групування таблиць за назвою колонки: sortBy<T>(items: T[], key: keyof T);
  • перелік дозволених полів для фільтрів, форм, експорту;
  • основа mapped types: { [K in keyof T]: ... }.

Особливості:

  • з індексною сигнатурою keyof дає ширший тип. Для { [key: string]: number } результат - string | number, бо в JavaScript числові ключі об'єкта перетворюються на рядки (obj[1] - те саме, що obj['1']);
  • для масивів keyof string[] містить number і назви методів масиву ('length' | 'push' | ...);
  • лише ключі типу, а не значення: keyof працює з типами. Щоб отримати ключі значення, потрібне keyof typeof config.

Пастка з Object.keys: Object.keys(user) повертає string[], а не (keyof User)[]. Це навмисно: через структурну типізацію в об'єкті під час виконання можуть бути й інші поля, яких немає в типі. Тому for (const key of Object.keys(user)) user[key] - помилка типу, і доводиться або звужувати ключ, або використовувати Object.entries.

Докладніше в документації: Оператор keyof

Перевір себе

20 випадкових питань за спробу, після завершення - розбір кожної помилки

Схожі питання