Index Access Types
Що таке Index Access Type
Ідея проста:
Якщо у нас є об'єктний тип
T, ми можемо звернутися до його властивості за ключемKі отримати тип цієї властивості.
Синтаксис:
T[K]де
T- тип об'єкта,K- ім'я (або об'єднання імен) ключівT.
Приклад 1. Просте звернення
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.
Можна брати кілька ключів одразу
type User = {
id: number;
name: string;
isAdmin: boolean;
};
type StringFields = User["name" | "isAdmin"];
// string | booleanTypeScript створює об'єднання типів властивостей.
Використання з keyof
Часто використовують keyof (який повертає об'єднання імен властивостей):
type User = {
id: number;
name: string;
age: number;
};
type ValueOfUser = User[keyof User];
// number | stringЦе аналог виразу "усі можливі типи значень об'єкта".
Приклад 2. Вкладені властивості
Можна звертатися до вкладених типів:
type Post = {
author: {
name: string;
age: number;
};
content: string;
};
type Author = Post["author"]; // { name: string; age: number }
type AuthorName = Post["author"]["name"]; // stringTypeScript обчислює тип рекурсивно.
Приклад 3. Динамічне використання з generic
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 можна використовувати і для масивів:
type Numbers = number[];
type Element = Numbers[number];
// numberЦе стандартний прийом, щоб "витягнути" тип елемента масиву.
Більш конкретний приклад:
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 типів:
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 перевіряє, що ви звертаєтеся до наявної властивості:
type User = { id: number; name: string };
type X = User["email"];
// Помилка: Property 'email' does not exist on type 'User'Це запобігає одруку і невалідним зверненням.
Приклад 7. Універсальний тип "ValueOf"
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
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["id" |
З keyof | Отримати об'єднання всіх типів значень | User[keyof User] |
| Для масиву | Видобути тип елемента масиву | T[number] |
| Вкладені | Можна звертатися до ланцюжка властивостей |
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.