为了实现这一点,您希望MyType
等于union type:
type MyType = {myProp: "propA", propA: any} | {myProp: "probB", propB: any}
这具有以下理想行为:
const goodObjA: MyType = {
myProp: "propA",
propA: "some value"
} // okay
const badObjA: MyType = { // error! Property propA is missing
myProp: "propA",
}
const goodObjB: MyType = {
myProp: "propB",
propB: "some value"
} // okay
const badObjB: MyType = {
myProp: "propB",
propA: "oops" // error, unexpected property
}
因此,现在唯一的问题是如何从MyUnionType
中以编程方式生成MyType
.从概念上讲,我们希望在MyUnionType
并集中获取每个成员K
,并生成一个新的{ myProp: K } & { [P in K]: any }
并集(其具有myProp
类型的属性K
和K
类型的键控属性any
).也就是说,我们希望在MyUnionType
并集中执行type F<K> = { myProp: K} & { [P in K]: any }
操作.
有几种方法可以做到这一点,但我的方法是按照microsoft/TypeScript#47109年创造的distributive object type.这个 idea 是在MyUnionType
中的K
上各画一个mapped type,然后立即用MyUnionType
画一个index into it,生成所需的并集:
type MyType = { [K in MyUnionType]:
{ myProp: K } & { [P in K]: any }
}[MyUnionType]
其计算结果为
type MyType =
({ myProp: "propA"; } & { propA: any; }) |
({ myProp: "propB"; } & { propB: any; });
这相当于我们想要的类型.
Playground link to code