Skip to main content

Що таке index access types?

Що таке Index Access Type

Ідея проста:

Якщо в нас є об'єктний тип T, ми можемо звернутися до його властивості за ключем K і отримати тип цієї властивості.

Синтаксис:

javascript
T[K]

де

  • T - тип об'єкта,
  • K - ім'я (або об'єднання імен) ключів T.

Приклад 1. Просте звернення

javascript
type User = { id: number; name: string; isAdmin: boolean; }; type IdType = User["id"]; // number type NameType = User["name"]; // string type Flags = User["isAdmin"]; // boolean

Так само, як і при доступі до властивості об'єкта в JS (user["id"]), у TS ми отримуємо тип цієї властивості - number.

Можна брати декілька ключів одразу

javascript
type User = { id: number; name: string; isAdmin: boolean; }; type StringFields = User["name" | "isAdmin"]; // string | boolean

TypeScript створює об'єднання типів властивостей.

Використання з keyof

Часто використовують keyof (який повертає об'єднання імен властивостей):

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

Це аналог вислову «усі можливі типи значень об'єкта».

Приклад 2. Вкладені властивості

Можна звертатися до вкладених типів:

javascript
type Post = { author: { name: string; age: number; }; content: string; }; type Author = Post["author"]; // { name: string; age: number } type AuthorName = Post["author"]["name"]; // string

TypeScript обчислює тип рекурсивно.

Приклад 3. Динамічне використання з generic

javascript
type PropType<T, K extends keyof T> = T[K]; type User = { id: number; name: string; }; type IdType = PropType<User, "id">; // number type NameType = PropType<User, "name">; // string

Тут PropType<T, K> - це узагальнений «getter» для типу властивості. Це часто використовується в бібліотеках (наприклад, React, Redux, Prisma тощо).

Приклад 4. Робота з масивами та кортежами

Index access type можна використовувати і для масивів:

javascript
type Numbers = number[]; type Element = Numbers[number]; // number

Це стандартний прийом, щоб «витягнути» тип елемента масиву.

Більш конкретний приклад:

javascript
const users = [ { id: 1, name: "Tom" }, { id: 2, name: "Bob" }, ]; type User = (typeof users)[number]; // { id: number; name: string }

(typeof users)[number] дістає тип одного елемента масиву users.

Приклад 5. У зв'язці з mapped types

Index Access часто використовується всередині mapped типів:

javascript
type User = { id: number; name: string; isAdmin: boolean }; type Nullable<T> = { [K in keyof T]: T[K] | null; }; type NullableUser = Nullable<User>; /* { id: number | null; name: string | null; isAdmin: boolean | null; } */

Тут T[K] використовується, щоб «взяти» тип вихідної властивості і модифікувати його.

Приклад 6. Обмеження ключів

TypeScript перевіряє, що ви звертаєтеся до наявної властивості:

javascript
type User = { id: number; name: string }; type X = User["email"]; // Помилка: Property 'email' does not exist on type 'User'

Це запобігає помилкам у написанні та невалідним зверненням.

Приклад 7. Універсальний тип «ValueOf»

javascript
type ValueOf<T> = T[keyof T]; type User = { id: number; name: string; isAdmin: boolean; }; type UserValue = ValueOf<User>; // number | string | boolean

Дуже часто використовується в утилітах і бібліотеках (наприклад, для типів Redux action values або enum values).

Приклад 8. Отримання типу з enum

javascript
enum Status { Success = "success", Error = "error", } type StatusType = Status[keyof typeof Status]; // "success" | "error"

Ключові застосування Index Access Types

  • Отримання типу поля з інтерфейсу
  • Отримання типу елемента масиву (T[number])
  • Динамічна генерація нових типів (у mapped types)
  • Обмеження generic-параметрів (K extends keyof T)
  • Створення універсальних утиліт (ValueOf, PropType, ReturnOf тощо)

Підсумок

ПоняттяОписПриклад
Index Access TypeОтримання типу властивості за її ключемUser["name"] → string
Множинний доступМожна вказати декілька ключівUser["name" | "isAdmin"]
З keyofОтримати об'єднання всіх типів значеньUser[keyof User]
Для масивуОтримати тип елемента масивуT[number]
ВкладеніМожна звертатися до ланцюжка властивостейPost["author"]["name"]

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

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

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