如何在TypeScript中添加基于另一个属性值的动态解析属性类型?

6xfqseft  于 2022-11-26  发布在  TypeScript
关注(0)|答案(2)|浏览(122)

我已经使用了多态关系。所以,现在我有下面的TypeScript接口:

interface SubjectA {}
interface SubjectB {}
interface SubjectC {}

enum SubjectType {
  SubjectA = 'Subject A',
  SubjectB = 'Subject B',
  SubjectC = 'Subject C',
}

interface ExampleSubject {
  type: SubjectType;
  subject: SubjectA | SubjectB | SubjectC
}

在这个例子中,你可以看到,ExampleSubject.subject有三种可能的主题类型(SubjectASubjectBSubjectC)。现在我希望它动态地解析它的类型。例如,如果ExampleSubject.typeSubjectType.SubjectA,那么ExampleSubject.subject应该是SubjectA
请指导我,我该如何解决这个问题?谢谢

brvekthn

brvekthn1#

这可以通过区分联合类型(docs)来实现
第一个
TypeScript游戏场
注意:SubjectX接口定义需要在某些方面有所不同,否则TypeScript会将它们折叠成相同的概念,它们实际上是同一接口的三个别名(因此无法区分)。

k7fdbhmy

k7fdbhmy2#

为此,你应该使用一个判别并集而不是接口。你已经有了判别式(SubjectType)。下面是你如何编写这个并集:

type ExampleSubject =
    | { type: SubjectType.SubjectA; subject: SubjectA }
    | { type: SubjectType.SubjectB; subject: SubjectB }
    | { type: SubjectType.SubjectC; subject: SubjectC };

然后,如果您有x,其类型为ExampleSubject,则可以通过检查x.type来缩小x.subject的类型:

if (x.type === SubjectType.SubjectA) {
    console.log(x.subject);
    //             ^? (property) subject: SubjectA
}

Playground示例
请注意,我在SubjectASubjectBSubjectC中放置了一些内容,以便TypeScript可以区分它们。由于TypeScript的类型系统是 structural,而不是 nominal,因此在创建类似上面的示例类型时,在类型中放置一些内容以区分它们是很重要的。否则,它们彼此兼容,这可能会将您带入错误的道路...

相关问题