Запропонувати правкуПокращити цю статтюДопрацюйте відповідь до «Index Access Types». Ваші зміни проходять модерацію перед публікацією.Потрібне підтвердженняКонтентЩо ви змінюєте🇺🇸EN🇺🇦UAПереглядЗаголовок (UA)Коротка відповідь (UA)Якщо у нас є об'єктний тип `T`, ми можемо звернутися до його властивості за ключем `K` і отримати **тип цієї властивості**: `T[K]`. **Ключове:** так само, як при доступі до властивості об'єкта в JS (`user["id"]`), у TS ми отримуємо тип цієї властивості.Показується над повною відповіддю для швидкого нагадування.Відповідь (UA)Зображення## Що таке 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["id" | | **З** `keyof` | Отримати об'єднання всіх типів значень | `User[keyof User]` | | **Для масиву** | Видобути тип елемента масиву | `T[number]` | | **Вкладені** | Можна звертатися до ланцюжка властивостей | |Для рев’юераПримітка для модератора (необов’язково)Бачить лише модератор. Прискорює рев’ю.