我有一个在对象数组类型中设置的联合类型,我在其中动态循环和使用。当我将对象设置为变量时,使用 if 情况检查其类型,然后访问它,该类型是从联合类型中正确选取的。但是,如果我用方括号动态访问对象,类型仍然是联合类型。
enum types {
FOO = 'FOO',
BAR = 'BAR',
FAS = 'FAS',
}
// example objects
type TObject_FOO = {
id: string
type: types.FOO
}
type TObject_BAR = {
id: string
type: types.BAR
}
type TObject_FAS = {
id: string
type: types.FAS
}
// utility class
type TPossibleObjectType = TObject_FOO | TObject_BAR | TObject_FAS
type Example<T = TPossibleObjectType> = {
id: string
currentObjectId: string
list: Record<string, T>
}
const dummy: Example<TObject_FOO | TObject_BAR> = {
id: 'ex',
currentObjectId: 'object_foo',
list: {
object_foo: {
id: 'object_foo',
type: types.FOO,
},
object_bar: {
id: 'object_bar',
type: types.BAR,
},
},
}
// This works as expected
const test = dummy.list.test
if (test.type === types.BAR) {
// since we are checking type from enum
// typeof assign here is infered as TObject_BAR, which is correct
const assign = test
}
// This doesnt work
if (dummy.list[dummy.currentObjectId].type === types.BAR) {
// type of assign is still union type
// which is: types.FOO | types.BAR
const assign = dummy.list[dummy.currentObjectId].type
}
我尝试了不同的选项并尝试正确搜索它,但由于我什至无法正确解释问题,所以我找不到正确的解决方案。我尝试过找到的不同/相似的解决方案,也尝试编写一个映射器函数,但一段时间后就完全丢失了。感觉这要么不受支持,要么我做的事情完全错误。
Typescript 不知道您执行
dummy.list[dummy.currentObjectId]
的两个地方都是同一个对象。这样的事情编译器很难跟踪,尤其是动态属性访问。
但是如果你只是将引用保存为常量,那么 Typescript 就可以很好地缩小该对象的类型。
const obj = dummy.list[dummy.currentObjectId]
if (obj.type === types.BAR) {
const assign = obj.type // types.BAR
}