通过键/方括号访问对象时使用联合类型进行类型推断

问题描述 投票:0回答:1

我有一个在对象数组类型中设置的联合类型,我在其中动态循环和使用。当我将对象设置为变量时,使用 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 union type-inference
1个回答
0
投票

Typescript 不知道您执行

dummy.list[dummy.currentObjectId]
的两个地方都是同一个对象。这样的事情编译器很难跟踪,尤其是动态属性访问。

但是如果你只是将引用保存为常量,那么 Typescript 就可以很好地缩小该对象的类型。

const obj = dummy.list[dummy.currentObjectId]
if (obj.type === types.BAR) {
  const assign = obj.type // types.BAR
}

看游乐场

© www.soinside.com 2019 - 2024. All rights reserved.