Пояснение
индексируемые типы в машинописи принимают только значения с точно таким же типом
Это очень близко, но не совсем правильно - подпись индекса должна содержать всех типов, которые отображаются с правой стороны.Это означает, что тип, используемый для индексации, может быть точно таким же, как ваши значения, но также может быть шире.
Что означает, что тип будет шире?Вы можете думать о типах множеств.Например, определенная строка, такая как "foo"
, относится к набору всех строк, поэтому string
шире, чем "foo"
.Типы вверху (any
и unknown
) содержат почти все, что означает, что им может быть назначено все.
Решение
Вы должны использовать индексподпись, которая содержит все возможные типы значений.
interface State {
[field: string]: ITEM | ITEM[] | null
}
или
interface State {
[field: string]: any;
}
Однако это уничтожит любое завершение кода.Если это подходит для вашего варианта использования, вы также можете попробовать этот подход:
type Foo = {
foo: number[]
bar: string[]
[index: string]: unknown;
}
const foo: Foo = {
foo: [1, 2, 3],
bar: ["a", "b", "c"],
baz: Window
}
В этом примере мы получаем правильные подсказки кода для foo
и bar
, и любые лишние свойства имеют тип unknown
.Это означает, что они должны быть проверены перед использованием.
let unrecognized = foo["baz"]
if (unrecognized instanceof Window) {
console.log(unrecognized.document);
}