Вопрос или проблема
Я получаю следующую ошибку, когда пытаюсь использовать динамическое значение в качестве ключа массива.
Элемент неявно имеет тип 'any', потому что выражение типа '`faults_${string}`' не может использоваться для индексации типа 'HeatsTable'.
export interface HeatsTable {
heat_id: UUID
start: number
faults_1: string[]
faults_2: string[]
faults_3: string[]
faults_4: string[]
}
const fault = heatData[`faults_${runningId}`]; // Выдает вышеуказанную ошибку TS
Использование keyof HeatsTable
работает, но вызывает ошибку на другой странице, потому что считает, что faults могут быть числом. Есть ли другое решение этой проблемы, которое я упускаю?
Ответ или решение
При работе с TypeScript и использованием динамических ключей в качестве индексов, может возникнуть множество ошибок, связанных с типами. В вашем случае, когда вы пытаетесь получить доступ к элементу массива с использованием динамического ключа, TypeScript сообщает о проблеме, связанной с типом any
. Это происходит из-за того, что компилятор не может подтвердить, что созданный ключ соответствует спецификации интерфейса HeatsTable
.
Понимание проблемы
Ваш код:
const fault = heatData[`faults_${runningId}`]; // Throws the above TS error
Сообщение о ошибке указывает на то, что выражение типа ‘faults_${string}
‘ не может использоваться для индексации типа ‘HeatsTable’. Это связано с тем, что TypeScript не может гарантировать, что строка, полученная в результате интерполяции, будет соответствовать одному из допустимых ключей в интерфейсе HeatsTable
.
Решение проблемы
Одним из подходов для решения этой проблемы является использование утверждения типов (type assertion). Это даст компилятору понять, что вы уверены в том, что ваш динамический ключ соответствует необходимому типу. Вот как это можно сделать:
const faultKey = `faults_${runningId}` as keyof HeatsTable;
const fault = heatData[faultKey];
В этом фрагменте кода мы явно указываем компилятору TypeScript, что faultKey
будет одним из ключей типа HeatsTable
, тем самым устраняя ошибку.
Альтернативные подходы
Если использование утверждений типов приводит к другим проблемам, например, если TypeScript воспринимает ваши данные как числа, вы можете рассмотреть следующие альтернативы:
- Использование условного типа:
Вы можете создать условия для проверки допустимых значений ключей. Если вашrunningId
всегда будет принимать значения от 1 до 4, можно создать четкий массив допустимых ключей.
const validKeys: Array<keyof HeatsTable> = ['faults_1', 'faults_2', 'faults_3', 'faults_4'];
if (validKeys.includes(`faults_${runningId}` as keyof HeatsTable)) {
const fault = heatData[`faults_${runningId}` as keyof HeatsTable];
}
- Создание вспомогательной функции:
Еще одно эффективное решение — создание вспомогательной функции, которая будет возвращать значения по динамическим ключам с проверкой типов.
function getFaultArray(heatData: HeatsTable, id: number): string[] | undefined {
const key = `faults_${id}` as keyof HeatsTable;
return heatData[key];
}
const fault = getFaultArray(heatData, runningId);
Заключение
Работа с динамическими ключами в TypeScript требует внимательного подхода к типам. Использование утверждений типов, массивов допустимых ключей или вспомогательных функций предоставляет вам гибкость и безопасность типов в коде. С правильным подходом вы сможете легко избежать ошибок компиляции и улучшить читаемость и поддержку вашего кода.