我无法理解TypeScript中术语 union types 和交集类型背后的逻辑。
实际上,如果不同类型的属性是属性集,如果我将它们与&
运算符组合在一起,则生成的类型将是这些集合的 union 。遵循这个逻辑,我希望像这样的类型被称为联合类型。如果我将它们与|
组合在一起,我只能使用它们的公共属性,即集合的交集。
Wikipedia似乎支持这种逻辑:
任何给定非空集S的幂集(所有子集的集合)形成布尔代数,集合的代数,具有两个运算∨:=∪(联合)和∧:=∩(交集)。
然而,根据typescriptlang.org,恰恰相反:&
用于生成交集类型,|
用于< em>联合类型。
我确定还有另一种看待它的方式,但我无法弄明白。
答案 0 :(得分:12)
这是考虑它的另一种方式。考虑四组:红色东西,蓝色东西,大事物和小东西。
如果你交叉所有红色东西和所有小东西的集合,你最终得到属性的 union - 集合中的所有内容都有红色财产和小财产。
但是如果您使用红色小东西和蓝色小东西的 union ,那么只有smallness属性在结果集中是通用的。 相交“红色小”与“蓝色小”产生“小”。
换句话说,取值域的并集会产生一组相交的属性,反之亦然。
答案 1 :(得分:8)
类型A | B
指的是 A
或B
的对象。换句话说,此类型的值来自A
的值的联合和B
的值。
类型A & B
指的是 A
和B
的对象。换句话说,此类型的值是从A
的值的交叉点和B
的值中提取的。
命名和语义在其他语言中是相同的,例如C ++。
答案 2 :(得分:5)
答案 3 :(得分:3)
在这种情况下,您不能将类型视为对象属性集。我们可以避免关于looking at scalar variables的联合和交集类型如何工作以及它们的允许值集(而不是对象)的困惑:
type A = 1 | 2
type B = 2 | 3
type I = A & B
type U = A | B
let a: A
let b: B
let i: I
let u: U
a = 1
a = 2
a = 3 // <- error
b = 1 // <- error
b = 2
b = 3
i = 1 // <- error
i = 2
i = 3 // <- error
u = 1
u = 2
u = 3
这里的“联合”和“交集”一词在应用于允许值集时与集合论术语完全对应。
Applying the notion of permissible values (instances) to object types有点棘手(因为集合论的类比不太适合):
type A = {
x: number
y: number
}
type B = {
y: number
z: number
}
type I = A & B
type U = A | B
A
的变量可以保存具有属性x
和y
(没有其他属性)的对象实例。B
的变量可以保存具有属性y
和z
(没有其他属性)的对象实例。I
的变量可以保存具有A
类型和B
类型(即x
,{ {1}}和y
;因此z
符号)对应于两种类型的属性的 union (因此很混乱)。&
的变量可以保存具有U
类型或A
类型属性的对象(逻辑或,不是XOR,即{ {1}}和B
,x
和y
或y
,z
和x
;因此y
符号),表示这两种类型的属性(在我们的示例中为z
)的交点存在(因此引起混淆)。|
答案 4 :(得分:1)
type A = {
a: number
b: number
}
type B = {
b: number
c: number
}
type C = A & B
type D = A | B
let a: A = { a: 2, b: 2 };
let b: B = { b: 2, c: 2 };
// intersection, narrow down, fewer options, like and, c have to match A and B
let c1: C = { a: 2, b: 2 }; // <- error
let c2: C = { b: 2, c: 2 }; // <- error
let c3: C = { a: 2, b: 2, c: 2 };
// union, broaden, more options, like or, d can match A or match B or match A and B
let d1: D = { a: 2, b: 2 };
let d2: D = { b: 2, c: 2 };
let d3: D = { a: 2, b: 2, c: 2 };
TypeScript操场单击here。
答案 5 :(得分:0)
我也有同样的问题,无法理解如何以相反的方式看待它。阅读答案后,我想我可以从语言学角度解释这两个词,提供两个词的不同含义,并为相反的命名方法留出空间。
比较单词 intersect 的以下含义:
这颗彗星的轨道与地球的轨道相交。
在此句子中,相交意为在一个点或一组点处相交。想一想两件事有共同点(例如一个点),而在其他方面却有所不同。这就是数学和SQL中的交集。
我们需要查明可实现的最大保护量与最高潜在财务收益相交的地方。
在这里 intersect 意味着聚在一起并互相影响,就像两件事成为一件新奇事物的组成部分一样。这就是TypeScript中的 一词的含义。
以类似的方式,您可以将 union 视为将不同事物结合在一起的行为,这在广义上就是 union在数学中的含义和SQL ;但这不仅意味着 joining ,而且意味着 joining具有共同的兴趣或目的,这与TypeScript中 union 的含义相对应。
受 intersect 的俄语译法的启发(不要问我为什么):пересекать(也可以交叉)和скрещивать(也是杂交)。
答案 6 :(得分:0)
type Head = {
skin: string,
bones: string,
nouse: number,
eyes: number,
ears: number
}
type Body = {
skin: string,
bones: string,
arms: number,
foots: number
}
type Frankenstein = Head | Body
let frank: Frankenstein
`1 rule (only Head)`
frank = {skin: 'green', bones: 'skull', nouse: 1, eyes: 2, ears: 2}
`2 rule (only Body)`
frank = {skin: 'gray', bones: 'skeleton', arms: 2, foots: 2}
`3 rule (Body and Head all together)`
frank = {
skin: 'green',
bones: 'skull',
nouse: 1,
eyes: 2,
ears: 2,
arms: 2,
foots: 2
}
`4 rule (Frank without arms or foots or ears or ...)`
frank = {
skin: 'green',
bones: 'skull',
nouse: 1,
eyes: 2,
ears: 2,
foots: 2
}
frank = {
skin: 'green',
bones: 'skull',
nouse: 1,
eyes: 2,
ears: 2,
arms: 2
}
frank = {
skin: 'green',
bones: 'skull',
nouse: 1,
eyes: 2,
arms: 2,
foots: 2
}
`-1 rule (he can't exist without general parts)`
frank = {
bones: 'skull',
nouse: 1,
eyes: 2,
ears: 2,
foots: 2} //error
frank = {
skin: 'green',
nouse: 1,
eyes: 2,
ears: 2,
arms: 2} //error
`-2 rule (and the MOST NOTABLY he can not exist without full kit of one of
his parts, why - ask his best friend - TypeScript)`
frank = {
skin: 'green',
bones: 'skull',
eyes: 2,
ears: 2,
foots: 2} //error
frank = {
skin: 'green',
bones: 'skull',
nouse: 1,
eyes: 2,
arms: 2
} //error