Интерфейс индексируемого типа, содержащий значения различных типов - PullRequest
0 голосов
/ 20 февраля 2019

Есть ли способ достижения разнообразия типов в интерфейсах индексируемых типов?

У меня есть состояние, содержащее поля разных типов.

public state:State = {
  item: {...},
  item1: {...},
  ...
  itemCollection: [],
  itemCollection1: [] 
  ...
}

В приведенном выше коде item isкакое-то конкретное имя, к которому я хочу получить доступ к состоянию, например this.state['item'].Но, насколько я понял, индексируемые типы в машинописи принимают только значения с точно таким же типом.

У меня есть такой интерфейс:

interface State{
  [field:string]: ITEM | ITEM[] | null
}

, который я хочу иметь возможностьпревратиться во что-то вроде этого:

interface State{
  [field:string]: ITEM | null
  [field:string]: ITEM[] | null
}

Я знаю, это выглядит глупо.Поскольку я новичок в TypeScript, мне интересно, смогу ли я сделать это так, как я это делал в JavaScript.

1 Ответ

0 голосов
/ 20 февраля 2019

Пояснение

индексируемые типы в машинописи принимают только значения с точно таким же типом

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

Что означает, что тип будет шире?Вы можете думать о типах множеств.Например, определенная строка, такая как "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);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...