Skip to main content

Оператор keyof

Що робить keyof

keyof бере тип об'єкта (інтерфейсу, класу, літералу тощо) і повертає об'єднання (union) усіх його ключів у вигляді рядкових (або числових) літералів.

Синтаксис:

javascript
keyof T

де T - це тип, у якого потрібно дістати ключі.


Приклад 1. Базовий приклад

javascript
type User = { id: number; name: string; isAdmin: boolean; }; type Keys = keyof User; // "id" | "name" | "isAdmin"

keyof User повернув об'єднання літеральних типів ключів

  • "id" | "name" | "isAdmin".

Як це працює

keyof не повертає значення, а створює тип, який являє собою множину імен властивостей об'єкта.

Можна думати про нього як про оператор Object.keys()

  • але той, що працює на рівні типів, а не в рантаймі.

Приклад 2. З типом із числовими ключами

javascript
type Matrix = { 0: string; 1: string; 2: string; }; type K = keyof Matrix; // "0" | "1" | "2"

Усі ключі стають рядковими літералами, навіть якщо в об'єкті були числа.


Приклад 3. Застосування з Record

javascript
type Permissions = Record<"read" | "write" | "delete", boolean>; type K = keyof Permissions; // "read" | "write" | "delete"

Приклад 4. Застосування з typeof

keyof часто використовують разом із typeof

  • щоб дістати ключі з реального об'єкта:
javascript
const user = { id: 1, name: "Tom", isAdmin: true, }; type UserKeys = keyof typeof user; // "id" | "name" | "isAdmin"

typeof user перетворює об'єкт на його тип, keyof typeof user дістає імена ключів.


Приклад 5. У зв'язці з Index Access Types

Зазвичай keyof використовують разом з оператором індексації T[K].

javascript
type User = { id: number; name: string; }; type ValueOfUser = User[keyof User]; // number | string

Так можна отримати тип усіх значень об'єкта, аналогічно Object.values() у JS.


Приклад 6. Обмеження generic-параметрів

keyof часто використовують для обмеження generic'ів

  • щоб дозволити передавати лише допустимі ключі.
javascript
function getProp<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; } const user = { id: 1, name: "Alex" }; getProp(user, "id"); // OK getProp(user, "email"); // Помилка: "email" не є ключем user

K extends keyof T каже: "K має бути одним із ключів типу T".


Приклад 7. Застосування до класів

javascript
class Point { x = 0; y = 0; move(dx: number, dy: number) {} } type Keys = keyof Point; // "x" | "y" | "move"

Приклад 8. З optional і readonly властивостями

keyof не змінює модифікатори властивостей (readonly, ?)

  • він просто повертає імена.
javascript
type Config = { readonly url: string; timeout?: number; }; type Keys = keyof Config; // "url" | "timeout"

Приклад 9. Застосування до union'ів

Якщо тип - об'єднання об'єктів, keyof повертає перетин їхніх ключів (лише спільні):

javascript
type A = { a: number; shared: string }; type B = { b: boolean; shared: string }; type Keys = keyof (A | B); // "shared"

Приклад 10. Застосування до масивів

Масиви в TS - це об'єкти, тому в них теж є ключі:

javascript
type K = keyof string[]; // number | "length" | "toString" | ...

Тобто keyof поверне і числові індекси, і стандартні методи масиву.


Застосування на практиці

Перевірка коректності ключів

javascript
function pick<T, K extends keyof T>(obj: T, keys: K[]): Pick<T, K> { const result = {} as Pick<T, K>; for (const key of keys) { result[key] = obj[key]; } return result; } const user = { id: 1, name: "John", isAdmin: true }; const partial = pick(user, ["id", "name"]); // працює

Підсумок

ПоняттяОпис
keyof TПовертає об'єднання імен ключів типу T
Тип результатуРядкові/числові літеральні типи ключів
Типове застосуванняK extends keyof T, T[keyof T], keyof typeof obj
Аналог у JSСхожий на Object.keys(obj) - але працює на рівні типів
Використовується вPick, Record, Partial, Omit, generic-функціях та ін.

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

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

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