前言
在初步學習了 TypeScript 的變量聲明後,對它的靜態類型檢查功能簡直是愛不釋手,但同時也發現一個問題:在正常的開發中,一個變量的類型有時可能不僅僅只限於 number 或者 string 中的一種,有可能是兩種類型或者更多,比如:
// index.js
let res;
if(userInfo.age && userInfo.age > 12){
res = userInfo.age;
}else{
res = userInfo.name;
}
上面例子中的 res 類型可能是 number,也可能是 string。
到底該怎樣限制 res 的類型,讓它同時滿足 number 和 string 的類型檢查呢?這就涉及到我們今天要學的 TypeScript 的另一種類型聲明——聯合類型。
關於聯合類型
從字面意思來看,所謂“聯合類型”其實就是多種類型的聯合,也就是不僅僅一種類型。
聯合類型(Union Types)可以通過管道(|)給變量設置多種類型,賦值時可以根據設置的類型來賦值。
基本語法如下:
let tag:Type1|Type2|Type3
其中使用“|”分隔的三種類型代表變量 tag 可被賦值的類型範圍。
注意:對於指定了聯合類型的變量,其值的類型必須只能是聯合類型中包含的某一種,如果取了聯合類型之外的類型值,在編譯過程中會報錯。
指定了聯合類型的變量可以在運行過程中被賦予聯合類型中的任一類型值。
實際使用示例
以下是聯合類型的幾種實際應用舉例。
聲明變量
let res: number | string; // 聯合類型聲明
if (userInfo.age > 12) {
res = userInfo.age;
} else {
res = userInfo.name;
}
return res;
上例中的 res 只能賦值爲 number 類型或 string 類型,賦值其它類型會產生報錯。
函數傳參
我們在函數傳參中也可以使用聯合類型來控制參數的預期類型:
function sayRes(res: number | string){
console.log(res);
}
sayRes(true); // Error: 類型“boolean”的參數不能賦給類型“string | number”的參數。
聯合類型數組
對於可能由不同單一類型元素組成的數組聲明,我們也可以使用聯合類型進行聲明。
let arr5: number[] | string[];
arr5[0] = true; // Error: 不能將類型“boolean”分配給類型“string | number”。
擴展知識
針對聯合類型的數據,主要擴展以下幾點。
只能訪問共有屬性或方法
一般情況下,使用聯合類型是因爲不能確定變量最終值的類型。
對於聯合類型的變量或參數,如果不能確定其具體類型的時候,只能訪問聯合類型中所有類型共有的屬性或方法,若訪問某一類型獨有的屬性或方法,會產生報錯。
function sayRes(res: number | string) {
if (res.length > 0) { // Error: 類型“number”上不存在屬性“length”。
}
}
當 res 爲 number 類型時,是不存在 .length
屬性的,所以會報錯。
下面這個例子中,因爲 .toString()
是 number 和 string 類型共有的方法,所以可正常編譯:
function sayRes(res: number | string) {
if (res.toString() === "12") {
}
}
類型推斷
對於聯合類型變量,在賦值後會根據值的類型推斷該變量的類型。
let res :number | string;
res = "編程三昧";
console.log(res.length);
res = 12;
console.log(res.length); // Error: 類型“number”上不存在屬性“length”。
在給 res 賦值爲 12 後,TypeScript 推斷 res 的類型爲 number,number 類型不存在 .length
屬性,所以報錯。
總結
以上就是 TypeScript 聯合類型的相關知識,總結起來就是:
- 聯合類型包含了變量可能的所有類型;
- 對聯合類型變量賦值爲聯合類型之外的值,會產生報錯;
- 在不能確定聯合類型變量的最終類型之前,只能訪問聯合類型所共有的屬性和方法。
~
~ 本文完,感謝閱讀!
~
學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!