TL;DR个
type ActorOrMagician = _GeneratedPersonType & { profession: ActorProfession | MagicianProfession }
TypeScrip有intersection types个;交叉点类型可分配给它的所有组成类型.
例如,两个对象类型的交集将创建一个包含这两个类型的所有成员的对象类型:
type A = { a: number }
type B = { b: string }
type C = A & B
// ^? { a: number; b: string }
你实际上已经try 过使用它,但并不完全正确.
type ActorOrMagician = _GeneratedPersonType & ActorProfession & MagicianProfession;
您正在try 将提取的profession
类型与根类型and with each other相交.由于它们不兼容,结果是never
*.
*类型为{ type: "actor" }
和{ type: "magician" }
.一个类型不能同时赋值给"actor"
和"magician"
,因此将它们相交产生{ type: never }
.然后,TypeScrip将这种"不可能的类型"简化为never
.
即使这是正确的,还有另一个问题:您直接将职业类型与根类型相交.这会将type
属性添加到新类型的根,而不是将对象添加到profession
属性.
So what you need to do is (A) use a union of the wanted professions and (B) use the correct structure.
The result is this:
type ActorOrMagician = _GeneratedPersonType & { profession: ActorProfession | MagicianProfession }
您可以看到我使用的是ActorProfession
和MagicianProfession
的union,并将它们与the same structure as 102放在一个对象中.
TypeScript Playground
As I noted before, you don't need to omit the profession
property from _GeneratedPersonType
first: that is the job of the intersection.
Intersections create a type that is assignable to all of the constituent types, so the resulting type will be at least as "narrow" as the "narrowest" type included.
从一个简单的 case 开始,您可以看到它是如何工作的:
type Fruits = "apples" | "oranges" | "bananas"
type ApplesAndOranges = "apples" | "oranges"
type t1 = Fruits & ApplesAndOranges
// ^? "apples" | "oranges"
// "bananas" is not assignable to "apples" | "oranges", so it is excluded.
你可以根据你的情况推断这一点:
type PersonType = {
profession:
| { type: "doctor" }
| { type: "actor" }
| { type: "magician" }
}
type t1 = PersonType & {
profession: { type: "actor" } | { type: "magician" }
}
// We can look at just that `profession` property:
type Professions =
| { type: "doctor" }
| { type: "actor" }
| { type: "magician" }
type t2 = Professions & ({ type: "actor" } | { type: "magician" })
// ^? { type: "actor" } | { type: "magician" }
// { type: "doctor" } is not assignable to { type: "actor" } | { type: "magician" }, so it is excluded.
// Therefore:
// t1 = {
// profession:
// | { type: "actor" }
// | { type: "magician" }
// }