可索引类型接口中有什么方法可以实现类型多样性?
我的状态包含不同类型的字段。
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一样做到这一点。
答案 0 :(得分:0)
说明
打字稿中的可索引类型仅接受完全相同的值 输入
那是非常接近的,但不是完全正确的-索引签名必须包含出现在右侧的所有类型。这意味着用于索引的类型可以与您的值完全相同,但也可以更宽。
一个类型变宽意味着什么?您可以认为类型是集合。例如,像"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);
}