我是打字稿新手。我一直在玩联合体和交集类型的形状,遇到了意料之外的事情……
如果我如下创建两个形状:
type Person = {
name: string,
occupation?: string
}
type Animal = {
name: string
gestationPeriodDays: number
}
然后我创建这两个形状的结合以及相交,就像这样...
type AnimalUnionPerson = Animal | Person
let humanzeeAllFields: AnimalUnionPerson = {
name: "Humanzee",
gestationPeriodDays: 60,
occupation: "Banana Farmer"
}
type AnimalIntersectPerson = Animal & Person
let animalIntersectPerson = {
name: "Shape Intersect",
gestationPeriodDays: 24,
occupation: "Data Scientist"
}
然后我创建了一个简单的函数,将交集类型作为参数...
function printOutIntersection(toPrint: AnimalIntersectPerson) {
console.log(toPrint.name)
console.log(toPrint.occupation) // With union of shapes, no need for User Defined Type Guard
console.log(toPrint.gestationPeriodDays)
}
现在,我可以将animalIntersectPerson
传递给函数,但是即使形状本身具有相同的字段,也不能将humanzeeAllFields
传递给函数。我希望能够给出TypeScript执行的结构类型检查。有人可以解释为什么会这样吗?
答案 0 :(得分:2)
事实上,AnimalUnionPerson
和AnimalIntersectPerson
没有提供相同的结构:
AnimalUnionPerson
- name //required
- occupation //optional
- gestationPeriodDays //Because of the union typing this is optional
AnimalIntersectPerson
- name //required
- occupation //optional
- gestationPeriodDays //in this case it's required
如您所见,gestationPeriodDays
的状态会根据使用并集键入或交集而改变。
答案 1 :(得分:2)
路口类型
当您拥有类型为Animal & Person
的值时,这意味着确保该值是Animal
和Person
。
联盟类型
给出类型为Animal | Person
的值时,它可以是Animal
或Person
。可能两者都有。与交集相比,不能保证该值同时为Animal
和Person
。
为表示一个值是Animal
XOR Person
,可以使用discriminated union type(求和类型)。
继续您的示例:
printOutIntersection
需要交集类型Animal & Person
。 humanzeeAllFields
是联合类型Animal | Person
,因此不能确保同时为Animal
和Person
。
由于Person
不是assignable到Animal
(仅Animal
具有gestationPeriodDays
属性),因此调用printOutIntersection
无效类型为humanzeeAllFields
的{{1}}。