可索引类型接口,包含各种类型的值

时间:2019-02-20 13:42:09

标签: reactjs typescript types interface

可索引类型接口中有什么方法可以实现类型多样性?

我的状态包含不同类型的字段。

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

item上方的代码中,我想使用this.state['item']之类的名称来访问该状态。但是,据我所知,打字稿中的可索引类型仅接受具有完全相同类型的值。

我有一个类似的界面

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

,我希望它可以变成这样:

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

我知道它看起来很蠢。由于我是TypeScript的新手,所以我想知道是否可以像过去使用JavaScript一样做到这一点。

1 个答案:

答案 0 :(得分:0)

说明

  打字稿中的

可索引类型仅接受完全相同的值   输入

那是非常接近的,但不是完全正确的-索引签名必须包含出现在右侧的所有类型。这意味着用于索引的类型可以与您的值完全相同,但也可以更宽。

一个类型变宽意味着什么?您可以认为类型是集合。例如,像"foo"这样的特定字符串属于所有字符串的集合,因此string"foo"宽。顶部的类型(anyunknown)包含几乎所有内容,这意味着可以将所有内容分配给它们。

解决方案

您必须使用包含所有可能类型的值的索引签名。

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
}

在此示例中,我们获得了foobar的正确代码提示,并且任何多余的属性均为unknown类型。这意味着它们必须经过验证才能使用。

let unrecognized = foo["baz"]

if (unrecognized instanceof Window) {
    console.log(unrecognized.document);
}