[英]Typescript: understanding union and Intersection types
我試圖對 typescript 中的 Union 和 Intersection 類型有一個直覺,但我無法弄清楚這種情況: Playground Link
interface A {
a: number;
}
interface B{
b: boolean;
}
type UnionCombinedType = A | B;
type IntersectionType = A & B;
const obj: UnionCombinedType = {
a: 6,
b: true,
}
const obj2: IntersectionType = {
a: 6,
b: true,
}
為什么我允許將兩個值都放在交集類型中? 兩個接口之間的交集是空的。 如果我將&
閱讀為AND
那么我很清楚為什么它允許我添加兩個道具,但是我應該閱讀|
關鍵字為OR
,我希望它允許我只分配a
或b
但不能同時分配兩者。
有人可以給我一些關於這些類型的直覺嗎?
鑒於以下情況:
interface A {
a: number;
c: number;
}
interface B{
b: boolean;
c: number;
}
聯合類型A | B
A | B
可分配給A
或B
。 它必須具有來自A
或B
(或兩者)的屬性
const oA: A | B = {
a: 6,
c: 6
}
const oB: A | B = {
b: true,
c: 6
}
const oC: A | B = {
a: 6,
b: true
c: 6
}
但是像A | B
這樣的類型有什么操作? A | B
有嗎? 只有屬於A
和B
的那些
oA.c = 1; // valid
交集類型A & B
,如果它可以分配給 A 和 B (因此必須具有 A 和 B 的屬性)。
const obj: A & B = {
a: 6,
b: true
}
更新
你問“為什么你的例子中的 A & B 可以使用 b 道具?它不能分配給類型 A”
這顯然不是真的。 任何具有 A 的所有屬性的類型都可以分配給 A。額外的屬性沒有害處:
const aAndExtraProp = {
a: 6,
d: 6
};
const ca0: A = aAndExtraProp;
您可能對 object 文字的過多屬性檢查感到困惑:
Object 文字在將它們分配給其他變量或將它們作為 arguments 傳遞時得到特殊處理並進行過多的屬性檢查。 如果 object 文字具有“目標類型”所沒有的任何屬性,您將收到錯誤消息:
const ca1: A = {
a: 6,
d: 6 //ERROR
};
從聯合類型接受什么的角度思考。 可以分配給字符串的一組事物 | number 字段是所有字符串的集合和所有數字的集合的並集。 可以分配給字符串和數字的一組東西什么都不是,因為在所有字符串的集合和所有數字的集合中沒有重疊。
我認為您將其描繪為字段上的集合運算符,而不是每種類型所代表的集合的集合運算符。
//////////////////////
這是數學術語:“類型”是其所有可能值的集合,例如 boolean = {true, false};。 現在類型 T 和 U 的並集是由 T 或 U 中的值組成的集合(即 T 與 U 合並); T 和 U 中值的類似交集(即它們的公共部分)。
如果成員在所有可能的值上,則該成員是可訪問的。 對於 union,類型 T|U 的值可能是 T 也可能是 U。我們不知道哪個是合法的,所以只有公共屬性是合法的。 如您所見,對類型的操作意味着對成員的不同但互補的操作。 這是德摩根定律的結果。
https://www.reddit.com/r/typescript/comments/9qduq3/why_is_type_intersection_called_like_that_its/
以下示例可以幫助您了解 TS 聯合和交叉點的工作原理:
interface A {
a1: string,
a2: string,
}
interface B {
b1: string,
b2: string;
}
type UnionAB = A | B;
type IntersectionAB = A & B;
const unionAB1: UnionAB = {
a1: 'xxx',
a2: 'xxx',
b1: 'xxx',
b2: 'xxx',
};
const unionAB2: UnionAB = {
a1: 'xxx',
a2: 'xxx',
};
const unionAB3: UnionAB = {
b1: 'xxx',
b2: 'xxx',
};
// Error
// Property 'a1' does not exist on type 'B'.
console.log(unionAB3.a1);
const unionAB4: UnionAB = {
a1: 'xxx',
a2: 'xxx',
b2: 'xxx',
};
// Error
// Property 'b1' does not exist on type 'UnionAB'.
// Property 'b1' does not exist on type 'A'.
console.log(unionAB4.b1);
// Error
// Type '{ a1: string; b2: string; }' is not assignable to type 'UnionAB'.
// Property 'b1' is missing in type '{ a1: string; b2: string; }' but required in type 'B'.
const unionAB5: UnionAB = {
a1: 'xxx',
b2: 'xxx',
};
const intersectionAB1 : IntersectionAB = {
a1: 'xxx',
a2: 'xxx',
b1: 'xxx',
b2: 'xxx',
};
// Error
// Type '{ a1: string; a2: string; b1: string; }' is not assignable to type 'IntersectionAB'.
// Property 'b2' is missing in type '{ a1: string; a2: string; b1: string; }' but required in type 'B'.
const intersectionAB2 : IntersectionAB = {
a1: 'xxx',
a2: 'xxx',
b1: 'xxx',
};
// Error
// Type '{ a2: string; b1: string; b2: string; }' is not assignable to type 'IntersectionAB'.
// Property 'a1' is missing in type '{ a2: string; b1: string; b2: string; }' but required in type 'A'.
const intersectionAB3 : IntersectionAB = {
a2: 'xxx',
b1: 'xxx',
b2: 'xxx',
};
想想你可以分配給這些類型的值,而不是相交和合並類型本身。
type I = string & number;
type U = string | number;
const i: I = 5;
失敗了,我們希望i
以某種方式同時成為字符串和數字,但那是不可能的( I
never
這里)。
const u: U = 5;
u
可以是字符串或數字,所以沒關系
回到你的例子:
const obj2: IntersectionType = {
a: 6,
b: true,
}
工作正常,因為 obj2 與IntersectionType
(同時具有屬性a
和b
)。 TypeScript 循環遍歷obj2
中的屬性,發現IntersectionType
的所有必要屬性都存在。
和
const obj: UnionCombinedType = {
a: 6,
b: true,
}
Typescript 看着obj
... obj
是否具有A
中所需的屬性? 是的。 TS就夠了。
如果您將屬性c
添加到兩個對象,TS 將失敗,因為它對於這兩種類型都是未知屬性,但那是另一回事。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.