前言
在初步學習了 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 聯合型別的相關知識,總結起來就是:
- 聯合型別包含了變數可能的所有型別;
- 對聯合型別變數賦值為聯合型別之外的值,會產生報錯;
- 在不能確定聯合型別變數的最終型別之前,只能訪問聯合型別所共有的屬性和方法。
~
~ 本文完,感謝閱讀!
~
學習有趣的知識,結識有趣的朋友,塑造有趣的靈魂!
本作品採用《CC 協議》,轉載必須註明作者和本文連結