使用类型提示动态确定正确的数据类型

Dynamically determine the correct type of data with a type hint

是否可以根据 'type-field' 以不同方式解释数据?

我正在加载数据(全部来自同一个文件)。我知道数据的类型,以及类型定义是什么样的。使用当前的 union 方法,它总是会显示所有字段,但我希望能够自动确定适用的类型。我可以在运行时转换类型,但这并不理想。

不确定我在这里是否将 TS 推得太多了,它是否应该符合实际的 loading/parsing 逻辑?

当前方法

enum MyTypes {
  TypeA = "A",
  TypeB = "B",
}
type IData = {
  type: MyTypes;
  data: IDataAllTypes <---- force the type to be `IDataTypeA` if the type field is `TypeA`
}
type IDataAllTypes = IDataTypeA | IDataTypeB

type IDataTypeA = {
  id: string
  age: number
  foo: string[]
}

type IDataTypeB = {
  id: string
  name: string
  bar: string[]
}

你可以这样做

enum MyTypes {
  TypeA = "A",
  TypeB = "B",
}

type IDataTypeA = {
  id: string
  age: number
  foo: string[]
}

type IDataTypeB = {
  id: string
  name: string
  bar: string[]
}

IDataA {
  type: MyTypes.TypeA,
  data: IDataTypeA,
}

IDataB {
  type: MyTypes.TypeB,
  data: IDataTypeB,
}

IDataAllTypes = IDataA | IDataB;

这叫做有区别的工会。它是一个联合类型,其中所有成员都有一个公共字段,可用于强制执行该类型的其余部分。

您可以这样声明IData

type IDataA = {
    type: MyTypes.TypeA,
    data: IDataTypeA
}

type IDataB = {
    type: MyTypes.TypeB,
    data: IDataTypeB
}
type IData = IDataA | IDataB

现在一切如您所愿:

const testA: IData = { type: MyTypes.TypeA, data: { id: 'qwe', age: 123, foo: ['a'] }}
const testB: IData = { type: MyTypes.TypeB, data: { id: 'qwe', name: 'asd', bar: ['b'] }}

// Type error. Can't pair type A with values from type B
const testFail: IData = { type: MyTypes.TypeA, data: { id: 'qwe', name: 'asd', bar: ['b'] }}

Playground