В JavaScript при создании объектов мы можем использовать разные значения в качестве ключей. Среди значений могут быть строки, числа или символы. Ровно такие же возможности TypeScript предоставляет для своих объектных типов, с которыми мы научимся работать в этом уроке.
В ходе курса мы уже работали с объектными типами и с интерфейсами, в которых имена полей заданы заранее. Давайте теперь познакомимся с синтаксисом для динамических ключей:
type dynamicKeysObject = {
[key: string | number | symbol]: unknown;
};
Здесь мы объявили объектный тип dynamicKeysObject
, в котором ключом может служить любой тип из доступных типов данных key: string | number | symbol
. Попробуем указать такой тип для переменной:
const obj: dynamicKeysObject = {
name: 'John',
age: 30,
0: 'zero',
[Symbol('secret')]: 'symbol',
};
Еще динамические ключи можно использовать совместно с указанными явно полями. Тогда ограничения динамических полей также будут распространяться и на них:
type MyTheme = {
palette: {
primary: 'red' | 'green' | 'blue';
[key: string]: string;
},
[key: string]: unknown;
};
const theme = {
palette: {
primary: 'red',
},
spacing: {
small: 8,
},
} satisfies MyTheme;
В примере мы явно указали тип для поля palette
, получили корректную проверку типа с помощью satisfies
и при этом оставили достаточно свободы для дальнейшего расширения темы.
Точно такой же синтаксис и поведение у динамических ключей в интерфейсах:
interface MyTheme {
palette: {
primary: string;
};
[key: string]: unknown;
}
В классах динамические ключи можно использовать для обычных и для static
полей:
class Template {
static [propName: string]: string | number;
[key: string]: string;
}
Template.test = 'test';
const template = new Template();
template.test = 'test';
Template String Literal
Динамические ключи полезны там, где нам неизвестны все возможные имена полей объекта, но мы все равно хотим ограничить их тип. В TypeScript тип ключа может также быть и шаблонным литералом. Для примера попробуем объявить тип слушателя и потребовать, чтобы все его методы начинались со слова on
:
type Listeners = {
[key: `on${string}`]: (value: unknown) => void
}
const streamListeners: Listeners = {
onStart() {},
onFinished() {},
};
Литеральный тип on${string}
нам говорит, что мы ожидаем строку по шаблону «строка начинается с on
, а дальше идет любая строка». Такая техника называется Template String Literal, она помогает наложить ограничения при типизации строк.
В типичном веб-приложении структура большинства объектов нам известна изначально. Потому использование динамических ключей чаще можно увидеть в библиотеках и вспомогательных функциях, которые мы и рассмотрим в следующих уроках.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.