Skip to content

2026-09-02

/ 11 分鐘閱讀

/ TypeScript Fundamentals

TypeScript 聯集與交集型別:用集合思維理解 | 與 & 的差異

用兩個具體的集合建立心智模型

前面已經零星看過幾次「或」的用法,這一節要正式深入聯集(union)與交集(intersection)型別,並延續一路以來把型別當成「允許值的集合」這個心智模型,用實際能驗證的例子建立直覺。

先建立兩個集合:一個是十以內的偶數,另一個是 1 到 5 的數字。畫成文氏圖來看,24 同時落在兩個圓圈的交集裡;「1 到 5」這個集合裡的 135 不是偶數,只落在自己的圓圈;而「偶數」集合裡的 68 都大於 5,也只落在自己的圓圈裡,兩邊各自都有一部分是對方沒有的。

聯集型別:型別世界裡的「或」

聯集型別對應到型別世界裡的「或」,TypeScript 用直式符號 | 表示:

ts
type OneThroughFive = 1 | 2 | 3 | 4 | 5;
type Evens = 2 | 4 | 6 | 8;

type OneThroughFiveOrEvens = OneThroughFive | Evens;
// { 1, 2, 3, 4, 5, 6, 8 }

這個符號的選擇不是隨便挑的,跟 JavaScript 裡表示邏輯「或」的雙直式符號 || 概念上是相關的,比較好記。如果把 OneThroughFive | Evens 這個集合想成一道門,站在門口的守門人只要值符合任何一邊的集合就會放行:只要是 1 到 5 之間,就能進去;只要是偶數,也能進去。結果就是把兩個集合的內容合併起來,1234568 全都在這個聯集型別裡,可以想像成先把第一個集合的所有值都收進來,再逐一檢查第二個集合裡的值,如果還沒收錄過就一併加進去,很像一個迴圈在背後跑過一輪。

兩種思考角度:能接受什麼,跟能保證什麼

理解聯集與交集型別時,有兩個角度值得分開思考:這個型別願意接受哪些值,以及對於集合裡的每一個成員,能確定保證什麼

以剛剛的聯集型別為例,它能接受兩個集合裡的任何一個值,接受範圍很寬。但反過來看能保證什麼:如果有一個函式只想要偶數,這個聯集型別的值不能直接拿去用,因為裡面可能混著 1 這種不是偶數的值;同樣地,如果函式只想要 1 到 5 之間的數字,也不能放心使用這個聯集型別,因為裡面可能是 68。這說明聯集型別雖然接受的值範圍變大了,但反而能對每個成員做出的保證變少了。

交集型別:型別世界裡的「且」

交集型別剛好相反,對應型別世界裡的「且」,TypeScript 用 & 符號表示,這個選擇同樣呼應了 JavaScript 邏輯運算子裡表示「且」的符號:

ts
type EvenAndOneThroughFive = Evens & OneThroughFive;
// { 2, 4 }

用同樣的兩個集合來看,交集型別得到的只有 24,也就是兩個集合共同擁有的值。這裡容易搞混的地方在於:講到「且」的時候,直覺上很容易誤以為是把兩個集合的內容全部加在一起,但其實交集型別問的是「這個值是否同時屬於這個集合,也屬於另一個集合」,只有真正兩邊都符合的值才能通過。可以想像成連續站著兩個守門人,任何一個值都得先後通過兩關審核,只要有一關不符合就會被擋下來,這也是為什麼交集型別最終產生的集合,範圍反而比原本任何一個集合都要小。

交集型別:範圍變窄,但保證變多

用前面「能接受什麼」跟「能保證什麼」這兩個角度重新檢視交集型別,會發現它跟聯集型別呈現完全相反的特性。就「能接受什麼值」來說,交集型別非常嚴格,一個值必須同時滿足兩邊的要求才能進來。但正因為這份嚴格,「能保證什麼」反而變得更豐富:如果有一個函式只想要偶數,交集型別裡的 24 都能直接拿去用,因為它們保證同時是偶數;如果另一個函式只想要 1 到 5 之間的數字,這個交集型別一樣能滿足,因為 24 也同時落在這個範圍內。換句話說,交集型別讓一個值同時符合多個約束條件的好處,是聯集型別做不到的。

這正是理解聯集與交集型別最核心的一組對照:聯集型別接受的值範圍變大,但對每個成員能做的保證變少;交集型別接受的值範圍變小,但對每個成員能做的保證反而變多。

複習

TypeScript 用什麼符號表示聯集型別與交集型別?

聯集型別用直式符號 | 表示,交集型別用 & 符號表示,這兩個符號的選擇都呼應了 JavaScript 裡表示邏輯「或」(||)與「且」(&&)的運算子,方便記憶。

思考聯集與交集型別時,有哪兩個互補的角度?

一個角度是「這個型別願意接受哪些值」,另一個角度是「對於集合裡的每一個成員,能確定保證什麼」。聯集型別接受的值範圍較大,但能做的保證較少;交集型別接受的值範圍較小,但能做的保證較多。

把「1 到 5」跟「十以內偶數」這兩個集合做交集,會得到什麼結果?

只會得到 24,也就是同時屬於兩個集合的值,因為交集型別要求一個值必須同時滿足兩邊的條件才能通過。

把「1 到 5」跟「十以內偶數」這兩個集合做聯集,會得到什麼結果?

會得到 {1, 2, 3, 4, 5, 6, 8},也就是把兩個集合的所有值合併起來,只要屬於任何一邊就會被納入聯集型別。

小測驗

TypeScript 用什麼符號表示聯集型別? `|`
交集型別的特徵是什麼? 只包含同時屬於兩個集合的值
給定「十以內偶數」(2、4、6、8)與「1 到 5」(1、2、3、4、5)這兩個集合,它們的聯集型別會包含哪些值? 1、2、3、4、5、6、8

此文章是 FrontendMasters 上的 TypeScript Fundamentals 課程筆記

最後更新時間:

Buy Me A Coffee

系列章節 第 10 篇 / 共 20 篇

0 %
MIT Licensed | Copyright © 2025-present Wen-Hsiu's Blog
Photo by Federica Galli on Unsplash