Ошибка типа ‘any’ в TypeScript с динамическим ключом массива

Вопрос или проблема

Я получаю следующую ошибку, когда пытаюсь использовать динамическое значение в качестве ключа массива.

Элемент неявно имеет тип '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 воспринимает ваши данные как числа, вы можете рассмотреть следующие альтернативы:

  1. Использование условного типа:
    Вы можете создать условия для проверки допустимых значений ключей. Если ваш 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];
}
  1. Создание вспомогательной функции:
    Еще одно эффективное решение — создание вспомогательной функции, которая будет возвращать значения по динамическим ключам с проверкой типов.
function getFaultArray(heatData: HeatsTable, id: number): string[] | undefined {
    const key = `faults_${id}` as keyof HeatsTable;
    return heatData[key];
}

const fault = getFaultArray(heatData, runningId);

Заключение

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

Оцените материал
Добавить комментарий

Капча загружается...