логотип PurpleSchool
Иконка входа
Вход
логотип PurpleSchool

Сигнатуры индекса в TypeScript

Автор

Дмитрий Нечаев

Сигнатуры индекса в TypeScript позволяют динамически определять свойства объектов и массивов, когда полные информации о структуре типов заранее не известны. Этот механизм особенно полезен при работе с данными, структура которых может изменяться в зависимости от условий выполнения программы.

Основы

Рассмотрим пример, когда вы заранее не знаете имена свойств объекта, но знаете типы значений, которые они могут принимать. В таких случаях можно использовать сигнатуру индекса для описания типов возможных значений. Например, определение интерфейса для массива строк:

interface StringArray {
  [index: number]: string;
}

const myArray: StringArray = getStringArray();
const secondItem = myArray[1];  // secondItem имеет тип string

В данном примере, интерфейс StringArray объявляет, что при обращении по числовому индексу, мы всегда получим строку.

Применение разных типов для индексов

TypeScript поддерживает использование строк или чисел в качестве ключей для сигнатуры индекса. Также возможно использование символов, шаблонных строк или объединений этих типов. Важно понимать, что значения, возвращаемые числовым индексатором, должны быть подтипом значений, возвращаемых строковым индексатором, так как JavaScript преобразует числовые ключи в строки:

interface Animal {
  name: string;
}

interface Dog extends Animal {
  breed: string;
}

// Ошибка: индексация числом может вернуть другой тип Animal
interface NotOkay {
  [x: number]: Animal;
  [x: string]: Dog;
}

Ограничения и возможности

Индексируемые типы мощный инструмент для работы со словарными структурами данных. Однако они также накладывают ограничения на соответствие типов свойств и значений:

interface NumberDictionary {
  [index: string]: number;
  length: number;  // допустимо
  name: string;    // ошибка: тип 'string' не присваиваем типу индекса 'number'
}

Однако, если индексируемый тип представляет собой объединение типов, это позволяет содержать свойства разных типов:

interface NumberOrStringDictionary {
  [index: string]: number | string;
  length: number;  // допустимо
  name: string;    // допустимо
}

Использование readonly

Для предотвращения изменения значений по индексам, можно использовать модификатор readonly:

interface ReadonlyStringArray {
  readonly [index: number]: string;
}

let myArray: ReadonlyStringArray = getReadOnlyStringArray();
// Ошибка: изменение значения по индексу запрещено
myArray[2] = "Mallory";

Заключение

Сигнатуры индекса в TypeScript предоставляют гибкость при работе с динамическими структурами данных, позволяя разработчикам определять интерфейсы для объектов и массивов с заранее неизвестными свойствами. Однако важно понимать ограничения, связанные с типами данных и их совместимостью, чтобы эффективно использовать эту возможность языка.

Карта развития разработчика

Получите полную карту развития разработчика по всем направлениям: frontend, backend, devops, mobile