联合类型数组和联合数组类型之间有区别吗?

Is there is a difference between array of union type and union array type?

考虑下一个代码:

type unionType = (A | B)[]
type unionArr = A[] | B[]

这两个选项有区别吗?

有区别。 (A | B)[] 表示可以存储类型 A 和类型 B 的项目的数组。 A[] | B[] 表示一个数组,其中所有项目都是 A 类型或所有项目都是 B

类型
class A { a = "a" }
class B { b = "b" }

type unionType = (A | B)[]
let ut: unionType;
ut = [new A(), new A()]
ut = [new B(), new B()]
ut = [new A(), new B()] // mixed array is fine

let uti = ut[0] // Reading we get A | B beacuse anythign can come out of the array

ut[0] = new B();
ut[1] = new A();

ut.reduce((s, e) => e instanceof A ? e.a + s: e.b + s, "") // ok

type unionArr = A[] | B[]
let uArr: unionArr;
uArr = [new A(), new A()]
uArr = [new B(), new B()]
uArr = [new A(), new B()] // mixed array is not fine

let uArri = uArr[0] // Reading we get A | B beacuse we don't kow if we have A[] or B[]

// Type gap: We can actually assign a B into uArr[0] event if it is holding a A[] 
uArr[0] = new B();
uArr[1] = new A(); 

// err This expression is not callable.
uArr.reduce((s, e) => e instanceof A ? e.a + s: e.b + s, "") 

Playground Link

对于A[] | B[],数组项必须全部为A或全部必须全部为B的约束仅在数组赋值时才真正检查,而不是在分配给不幸的是数组的索引。

此外,调用签名对联合的工作方式,您最终可能会得到 A[] | B[] 的 un-callable 函数,例如 reduce(例如 map 将起作用)

我通常会坚持使用 (A | B)[],除非有充分的理由支持另一个超过它的问题。