Indexed Access Types (или типы доступ по индексу) позволяют ссылаться на тип конкретного свойства объекта или любого ключа через синтаксис T[K]. Это мощный инструмент для создания гибких и типобезопасных абстракций.
type Person = { name: string; age: number; }; type NameType = Person['name']; // string type AgeOrName = Person['age' | 'name']; // number | string
Используется для написания универсальных типов и функций:
function getProperty<T, K extends keyof T>(obj: T, key: K): T[K] { return obj[key]; // корретная типизация возврата } const user = { email: 'a@a.ru', id: 1 }; let id = getProperty(user, 'id'); // id: number
Person['salary'] — ошибка на этапе компиляции.Вопрос: Какой тип получится у выражения type Foo = {a: number, b: string}["a" | "b" | "c"]?
Ответ: Этот пример вызовет ошибку компиляции, потому что 'c' не является ключом в типе, к которому осуществляется доступ. TypeScript выдаст ошибку:
Type '"c"' does not satisfy the constraint '"a" | "b"'.
История
В проекте динамически генерировались формы на основе типов. После добавления нового поля в основной тип не обновили места с индексацией по ключам, в результате некоторые свойства не попадали в форму, хотя на типовом уровне ожидался полный маппинг. Ошибка проявлялась только в runtime, а не на этапе разработки.
История
В библиотеке для валидации данных был использован индексируемый доступ через типы, но при миграции кода переместили один из ключей из объекта в родителя. Старый индексируемый тип приводил к ошибке компиляции, однако ошибка возникала только после пересборки из-за кэша в CI, и до этого жила на staging несколько недель.
История
Ошибочно полагали, что с помощью Indexed Access Types можно обращаться к любому ключу, даже если он не перечислен явно, что привело к неверной генерации автотестов для динамических свойств. В результате тесты не покрывали часть возможных сценариев, т.к. компилятор выбрасывал эти случаи как невалидные.