TypeScript的并集和交集类型的命名

sev*_*sik 35 boolean-logic set typescript

我无法理解TypeScript中术语联合类型交集类型背后的逻辑.

从务实角度来说,如果不同类型的属性是套房产,如果我与他们结合&操作,产生的类型将成为联盟的那些套.遵循这个逻辑,我希望像这样的类型被称为联合类型.如果我将它们组合在一起|,我只能使用它们的共同属性,即集合的交集.

维基百科似乎支持这种逻辑:

任何给定非空集S的幂集(所有子集的集合)形成布尔代数,集合的代数,具有两个运算∨:=∪(并集)和∧:=∩(交集).

但是,根据typescriptlang.org,它恰恰相反:&用于生成交集类型|用于联合类型.

我确信还有另一种方式来看待它,但我无法弄明白.

Rya*_*ugh 17

这是考虑它的另一种方式.考虑四组:红色东西,蓝色东西,大事物和小东西.

如果你将所有红色事物和所有小事物的集合相交,你最终会得到属性的联合 - 集合中的所有东西都包含red属性和小属性.

但是,如果你拿了工会红色小东西蓝色的小东西,只有渺小属性在结果集普遍. "红色小"与"蓝色小" 相交会产生"小".

换句话说,取值域的并集会产生一组相交的属性,反之亦然.

  • 从用户角度思考,“A 实现 B 或 C”和“A 实现 B 和 C”比“我们确信 A 具有 B 和 C 中的属性”和“A 具有任何属性”更清楚位于 B 或 C 中”。 (4认同)
  • 将现存对象分组为命名分类(我们现在称之为"类型")是人类数十万年来所做的事情. (3认同)
  • 谢谢,它非常具有描述性,并准确指出了我错在哪里:我在考虑属性集,而不是实例集。 (2认同)
  • 为什么将类型视为一组实例?实例是什么,类型是什么?哪种类型.. ?这是循环推理吗? (2认同)

小智 9

类型A | B是指或者是 A或者的对象B.换言之,这样的类型的值是从所绘制的联合对值的A值和B.

类型A & B是指是对象 AB.换句话说,这种类型的值是从值和值的交集中绘制的.AB

命名和语义在其他语言(如C++)中是相同的.


Dra*_*vuk 7

这里的混淆可能源于我们如何想象集合,即认为交集/联合涉及类型的成员而不是类型本身。我整理了一个图形,希望能澄清这个概念:

并/交图

  • 这个答案并没有真正解释显示_set union_的维恩图如何或为什么被用来描述_intersection type_(反之亦然,在第二行)。 (2认同)

Kai*_*ner 5

在这种情况下,您不能将类型视为一组对象属性。我们可以通过查看标量变量及其允许值集(而不是对象)来避免对联合和交集类型如何工作的混淆:

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
Run Code Online (Sandbox Code Playgroud)

这里的术语“联合”和“交集”在应用于允许值的集合时与集合论术语完全对应。

将允许值(实例)的概念应用于对象类型有点棘手(因为集合论类比并不适用):

type A = {
  x: number
  y: number
}

type B = {
  y: number
  z: number
}

type I = A & B
type U = A | B
Run Code Online (Sandbox Code Playgroud)
  • 类型变量A可以保存具有属性xy(没有其他属性)的对象实例。
  • 类型变量B可以保存具有属性yz(没有其他属性)的对象实例。
  • 在集合论中,上面两组对象实例的交集是空的。然而,可变交叉点型 I能够保持与类型的属性的对象A和那些类型的B(即xyz;因此,&符号),其对应于联合两种类型的属性(因此混乱)。
  • 在集合论中,上述两组对象实例的并集不包括具有所有三个属性的对象。但是,联合类型 的变量U可以保存具有类型AOR属性的对象B(逻辑 OR,而不是 XOR,即xand y, yand z, or x, y, and z; 因此是|符号),这意味着两个属性的交集类型(y在我们的示例中)保证存在(因此混淆)。
let i: I
let u: U

i = { x: 1, y: 2 };         // <- error
i = { y: 2, z: 3 };         // <- error
i = { x: 1, y: 2, z: 3 };

u = { x: 1, y: 2 };
u = { y: 2, z: 3 };
u = { x: 1, y: 2, z: 3 };
Run Code Online (Sandbox Code Playgroud)