Индексные сигнатуры строк и чисел
Разберитесь в правилах и особенностях числовых ключей
«Индексные сигнатуры строк и чисел» — бесплатный урок TypeScript Academy на CoddyKit. Это урок 2 из 4. Ты можешь прочитать весь урок бесплатно ниже — а потом практиковать его прямо в браузере с встроенным редактором кода и ИИ-репетитором 24/7. Это часть пути обучения TypeScript Academy, и твой прогресс синхронизируется между веб-версией и приложением CoddyKit. Курс TypeScript Academy содержит 4 уроков всего.
Два вида индексных ключей
TypeScript поддерживает сигнатуры индекса как для строк, так и для чисел. Они выглядят похоже, но ведут себя по-разному из-за особенностей хранения ключей объектов в JavaScript.
Числовая сигнатура индекса
Числовая сигнатура индекса { [i: number]: T } описывает объекты, к которым обращаются по числовой позиции, — прежде всего массивы и структуры, подобные массивам.
type NumberList = { [index: number]: string }
const names: NumberList = { 0: "ana", 1: "leo" }
console.log(names[0]) // anaJS преобразует числовые ключи в строки
Вот ключевой факт: ключи объектов JavaScript всегда являются строками. Когда вы пишете obj[0], движок фактически сохраняет ключ как строку "0". TypeScript моделирует эту реальность.
const obj: Record<string, string> = {}
obj[1] = "one"
console.log(obj["1"]) // one — same key!
console.log(Object.keys(obj)) // ["1"]Правило совместимости
Поскольку числовой ключ фактически является строкой, TypeScript устанавливает правило: когда у объекта есть и числовая, и строковая сигнатуры индекса, тип значения числового индекса должен быть совместим с типом значения строкового индекса.
interface Mixed {
[key: string]: string
[index: number]: string // must match the string value type
}
const m: Mixed = { 0: "a", name: "b" }
console.log(m[0], m.name)Зачем нужно это правило
Если obj[0] и obj["0"] указывают на один и тот же слот, тип значения не может быть числом в одном случае и строкой в другом. Поэтому тип значения числового индекса должен быть подтипом типа значения строкового индекса, чтобы сохранять согласованность.
// This is an ERROR:
// interface Bad {
// [key: string]: string
// [index: number]: number // number not assignable to string
// }Массивы с числовой индексацией
Массивы — основной пример типа с числовой индексацией. Встроенный тип Array<T> фактически имеет числовую сигнатуру индекса, поэтому arr[i] возвращает T.
const nums: number[] = [10, 20, 30]
const first: number = nums[0]
console.log(first + nums[2]) // 40Кортежи тоже используют числовую индексацию
Кортежи используют числовую индексацию, но закрепляют за конкретными позициями определённые типы. Доступ по числовому индексу за пределами диапазона использует объединение типов элементов или помечается как ошибка.
const pair: [string, number] = ["age", 30]
const label: string = pair[0]
const value: number = pair[1]
console.log(label + ": " + value)Строковый индекс допускает оба вида поиска
Объект со строковой сигнатурой индекса также принимает доступ с числовым индексом, поскольку сначала число преобразуется в строковый ключ.
type Bag = { [key: string]: number }
const b: Bag = {}
b[5] = 100 // stored as key "5"
console.log(b["5"]) // 100Числовой индекс не принимает строки
Обратное неверно. Объект, типизированный только числовой сигнатурой индекса, отклоняет строковые ключи на этапе компиляции, хотя JS технически разрешил бы такой доступ.
type OnlyNumbers = { [i: number]: string }
const o: OnlyNumbers = { 0: "x" }
// o.name = "y" // Error: property name not on number-indexed type
console.log(o[0])Как выбрать между ними
Используйте числовой индекс для данных, похожих на последовательность и основанных на позициях (списки, кортежи). Используйте строковый индекс для поиска по именам (словари, кэши). Если сомневаетесь, выбирайте строковый индекс как более универсальный.
type Positions = { [i: number]: { x: number; y: number } }
type ByName = { [name: string]: { x: number; y: number } }
const p: Positions = { 0: { x: 1, y: 2 } }
console.log(p[0].x)Практический смешанный объект
Можно объединить обе сигнатуры, если тип значения подходит для обеих. Это полезно для разреженных контейнеров, подобных массивам, которые также предоставляют именованные позиции.
interface Flexible {
[key: string]: number
[index: number]: number
}
const f: Flexible = { 0: 1, total: 99 }
console.log(f[0] + f.total) // 100Быстрая проверка
Проверьте, насколько вы поняли разницу между строковыми и числовыми сигнатурами индекса.
Итоги
Строковые и числовые сигнатуры индекса различаются, потому что JS хранит все ключи как строки, преобразуя числа в строковые ключи. Если существуют оба вида сигнатур, тип значения числового индекса должен быть совместим с типом значения строкового индекса. Числовая индексация описывает массивы и кортежи, а строковая — словари. Объекты со строковой индексацией допускают числовой доступ, но объекты с числовой индексацией отклоняют строковые ключи на этапе компиляции.
Часто задаваемые вопросы
Урок «Индексные сигнатуры строк и чисел» бесплатный?
Да — полный текст урока «Индексные сигнатуры строк и чисел» бесплатно доступен здесь в веб-версии. Чтобы практиковать его интерактивно (встроенный редактор кода и ИИ-репетитор 24/7) и разблокировать остальной курс TypeScript Academy, подпишись на CoddyKit PRO. Курс TypeScript Academy содержит 4 уроков всего.
Чему я научусь в уроке «Индексные сигнатуры строк и чисел»?
Разберитесь в правилах и особенностях числовых ключей Ты практикуешь TypeScript Academy с помощью реального кода, который запускаешь прямо в браузере, и ИИ-репетитор 24/7 отвечает на твои вопросы во время урока.
Нужен ли мне опыт, чтобы начать TypeScript Academy?
Предыдущий опыт не требуется. TypeScript Academy на CoddyKit структурирован для всех уровней — от новичков до продвинутых, поэтому ты можешь начать отсюда или с самого начала и учиться в своем темпе. Это урок 2 из 4.
Сколько времени занимает урок «Индексные сигнатуры строк и чисел»?
Большинство уроков CoddyKit занимают около 5–10 минут. Каждый из них компактный и интерактивный, поэтому ты постоянно делаешь прогресс и продолжаешь с того же места в веб-версии и приложении.
Можно ли писать и запускать код в этом уроке TypeScript Academy?
Да. Каждый урок TypeScript Academy включает встроенный редактор кода, поэтому ты пишешь и запускаешь реальный код прямо в браузере и получаешь моментальную обратную связь от AI — локальная установка не требуется.
Все уроки этого курса
- Определение индексных сигнатур
- Индексные сигнатуры строк и чисел
- Объединение известных и динамических ключей
- Индексные сигнатуры и Record