Изучаем продвинутую технику работы с типами — Indexed Access Types. Этот механизм позволяет «вытаскивать» тип конкретного свойства из другого типа, используя квадратные скобки, похоже на то, как мы получаем значения из массивов или объектов в JavaScript.
С помощью конструкции T[K] можно ссылаться на типы полей интерфейсов, не дублируя код. Это особенно полезно при поддержке больших проектов, когда изменение в одном интерфейсе должно автоматически подтягиваться в другие места. Мы также затронем использование операторов keyof и typeof для динамического получения ключей.
Вас ждут практические упражнения, где нужно определить правильный тип переменной, найти ошибку в синтаксисе и собрать корректную конструкцию.
- Модуль 1: Введение в TypeScript
- Модуль 2: Примитивные типы
- Модуль 3: Специальные типы
- Модуль 4: Массивы
- Модуль 5: Кортежи (Tuples)
- Модуль 6: Объекты
- Модуль 7: Функции
- Модуль 8: Union типы
- Модуль 9: Литеральные типы
- Модуль 10: Type Aliases
- Модуль 11: Интерфейсы
- Модуль 12: Type Guards и Narrowing
- Модуль 13: Enums
- Модуль 14: Классы
- Модуль 15: Generics — основы
- Модуль 16: Generics — ограничения
- Модуль 17: Utility Types — базовые
- Модуль 18: Utility Types — работа с Union
- Модуль 19: Utility Types — функции
- Модуль 20: Type Assertions
- Модуль 21: Keyof и Typeof операторы
- Оператор keyof.
- Оператор typeof в типах.
- Комбинация keyof typeof.
- Indexed Access Types.
- Модуль 22: Mapped Types
- Модуль 23: Conditional Types
- Модуль 24: Discriminated Unions
- Модуль 25: Модули и типы
- Модуль 26: Declaration Files
- Модуль 27: Типизация асинхронного кода
- Модуль 28: Практические паттерны
1. Поиск Indexed Access
Перед вами фрагмент кода на TypeScript, содержащий интерфейсы и объявления типов. Внимательно изучите код и найдите все места, где используется синтаксис Indexed Access Types — доступ к типу свойства объекта по ключу через квадратные скобки (например, `Type['key']`). Отметьте только эти конструкции, не выделяя другие элементы кода, такие как имена интерфейсов, ключевые слова или объявления обычных типов.
interface User {
id: number;
name: string;
email: string;
}
interface Product {
id: number;
title: string;
price: number;
}
// Примеры использования Indexed Access Types
{{type UserId = User['id']~|~t1}};
{{type UserEmail = User['email']~|~t2}};
{{type ProductPrice = Product['price']~|~t3}};
// Другие объявления типов (не Indexed Access)
type UserKeys = keyof User;
type ProductType = Product;
function getProperty(obj: T, key: K): T[K] {
return obj[key];
} 2. Определение типа
Дан интерфейс Car с полями разных типов. Определите, какой тип TypeScript вернёт выражение Car['model']. Введите название типа в поле ответа. Обратите внимание, что тип должен быть указан в том виде, в котором он используется в TypeScript (например, string, number, boolean).
interface Car {
brand: string;
model: string;
year: number;
color: string;
}
// Какой тип вернёт выражение Car['model']?3. Доступ к вложенному типу
В этом задании вам нужно использовать indexed access types (типы доступа по индексу) для извлечения вложенных типов из сложной структуры. Дополните код, указав правильные ключи в квадратных скобках, чтобы получить доступ к типу 'details' и типу 'name' внутри него. Обратите внимание на структуру объекта 'Product' и используйте операторы keyof и typeof для получения нужных типов.
type Product = {
id: number;
details: {
name: string;
price: number;
};
};
const productExample = {
id: 1,
details: {
name: 'Laptop',
price: 999
}
};
// Получите тип свойства 'details' из типа Product
type DetailsType = Product[input1S];
// Получите тип свойства 'name' из типа details, используя переменную productExample и typeof
type NameType = typeof productExample[input2S]['name'];4. Типы выражений
Перед вами список выражений, использующих indexed access types (типы доступа по индексу) для интерфейса Product. Ваша задача — распределить каждое выражение в одну из двух категорий: выражения, которые возвращают тип `string`, и выражения, которые возвращают тип `number`. Обратите внимание, что тип выражения определяется типом свойства интерфейса Product, к которому осуществляется доступ. Интерфейс Product определён следующим образом: `interface Product { id: number; name: string; price: number; description: string; category: string; inStock: boolean; }`.
Product['name']Product['id']Product['price']Product['description']Product['id'] | Product['price']Product['name'] | Product['description']5. Несуществующий ключ
В этом фрагменте TypeScript-кода используется indexed access type для получения типа свойства интерфейса. Однако в коде допущена ошибка: указан несуществующий ключ (опечатка). Вам нужно найти и исправить эту ошибку, чтобы код стал корректным и компилировался без ошибок.
interface User { name: string; age: number; email: string;} type UserName = User['naem']; // Опечатка в ключе6. Логика разрешения типа
Проанализируйте TypeScript-код сверху и восстановите последовательность шагов, которые TypeScript выполняет для вычисления типа `T[keyof T]`. Шаги снизу перемешаны — расставьте их в правильном порядке, чтобы отразить логику разрешения типа от определения исходного типа до получения итогового union-типа значений.
type Person = {
name: string;
age: number;
city: string;
};
// Используем Indexed Access Types с keyof
type PersonValues = Person[keyof Person]; // Результирующий тип
// Пример объекта для наглядности
const person: Person = {
name: "Alice",
age: 30,
city: "London"
};keyof к типу T для получения union-типа всех его ключей: keyof Person → "name" | "age" | "city"T (в примере: Person с полями name: string, age: number, city: string)string | numberstring | number | stringkeyof T TypeScript обращается к соответствующему типу значения в T через Indexed Access7. Массивы и индексы
В этом задании вам нужно заполнить пропуски в коде TypeScript, чтобы получить тип элемента массива с помощью indexed access types. Для этого используется ключевое слово `number` в конструкции `Type[number]`. Выберите из выпадающего списка правильные варианты для каждого пропуска, чтобы код стал корректным и компилировался без ошибок.
type Colors = string[];
type Color = Colors[input1S];
type Numbers = number[];
type NumberType = Numbers[input2S];
type Booleans = boolean[];
type BooleanType = Booleans[input3S];
type Mixed = (string | number)[];
type MixedType = Mixed[input4S];