TypeScript позволяет описать объекты с динамическими именами свойств, когда невозможно заранее определить все ключи. Для этого используются index signatures, появившиеся как способ типизации объектов-вариативов (map, данные с внешнего сервера и т.д.).
Без index signature объект воспринимается только по заранее заданным ключам, любые другие будут вызывать ошибку компиляции. При этом некорректное объявление сигнатуры может размыть типы всех свойств объекта, снизить типовую строгость и привести к багам.
Явно объявляйте index signature только там, где это оправдано. Для типизации массива объектов по строковому ключу используйте следующую форму:
Пример кода:
interface Dictionary { [key: string]: number; length?: number; } const sample: Dictionary = { apples: 4, oranges: 10 }; sample['bananas'] = 6;
Ключевые особенности:
Можно ли задать разные типы значений для разных ключей в index signature?
Нет, тип вра‘щается на всем наборе ключей, если вы укажете [key: string]: number, то и sample.length должен быть number: это часто вызывает ошибку при совместном использовании index signature и известных свойств.
Можно ли использовать index signature с символами (symbol)?
Да, начиная с ES6 TypeScript поддерживает index signature по символу:
interface SymbolMap { [key: symbol]: string; }
Что произойдёт, если объявить объект с index signature и дополнительными свойствами другого типа?
Компилятор выдаст ошибку, если тип свойства не совместим с объявленным типом значения index signature. Можно обойти это использованием union-типа или вынести такие поля в отдельный интерфейс.
Для любого ответа с сервера использовался интерфейс {[key: string]: any}, что приводило к проникающим багам из-за потери контроля над структурой данных.
Плюсы:
Минусы:
Использование index signature строго для dictionaries (например, конфигурация по ключу), а явно известных свойств — только с декларацией их типа вне сигнатуры.
Плюсы:
Минусы: