@
型別約束
TypeScript中的型別是一種用於描述變數、函式引數和函式返回值的特徵的方式。
程式碼中定義型別的部分不會在原生JavaScript環境中編譯
基本型別
包括number、string、boolean、null、undefined和symbol。
聯合型別
聯合型別(Union Types)是指用“|”符號將多個型別組合成一個的型別。這意味著一個變數可以儲存多種型別的值
let value: number | string = 42;
控制流分析
TypeScript 本身是一種靜態型別語言,它在編譯時進行型別檢查,因此控制流分析在編譯階段就已經開始了
比如:
function getUserInput():string|number{
if(new Date() != new Date("2023-11-01")){
return "yes";
}
else {
return 0;
}
}
此時Typescript的控制流分析將data型別視為 string | number
instanceof和typeof
typeof運算子用於獲取一個值的型別。它返回一個字串,表示值的型別
instanceof運算子用於判斷一個物件是否屬於某個類的例項
使用typeof input === "string" 和 input instanceof String 這兩個判斷有什麼區別:
typeof只能用於判斷基本型別,instanceof可以用於判斷自定義的型別,例如類,介面,陣列等
instanceof 可以用於判斷一個物件是否是某個類的例項,包括繼承自該類的子類。
型別守衛和窄化
型別守衛用於獲取變數型別資訊,通常使用在條件塊語句中。型別守衛是返回布林值的常規函式,接受一個型別並告訴 TypeScript 是否可以縮小到更具體的型別。
縮小到更具體的型別的過程稱之為“窄化(Narrowing)”,它能根據程式碼中的邏輯減少聯合中的型別數量。大多數窄化來自if語句中的表示式,其中不同的型別運算子在新的範圍內窄化。
typeof判斷
var input = getUserInput()
input // string |number
if (typeof input === "string") {
input // string
}
instanceof判斷
var input = getUserInput()
input // number | number[]
if (input instanceof Array)) {
input // number[]
}
in判斷
var input = getUserInput()
input // string | {error: ...}
if ("error" in input) {
input // {error: ...}
}
內建函式,或自定義函式
var input = getUserInput()
input // number | number[]
if (Array.isArray(input)) {
input // number[]
}
// 驗證是否是number型別
function isNumber(x: any): x is number {
return typeof x === "number";
}
// 驗證是否是string型別
function isString(x: any): x is string {
return typeof x === "string";
}
var input=getUserInput(); //string | number
if (isNumber(input)){
input // number
}
賦值
賦值過後的變數,也將發生“窄化”
let data: string | number = ..
data // string | number
data ="Hello"
data // string
布林運算
執行布林運算時在一行程式碼裡也會發生窄化
var input = getUserInput()
input // number | string
const inputLength = (typeof input ==="string" && input.length) || input //string
保留共同屬性
當聯合型別的所有成員都有相同的屬性名稱時,這些屬性會被保留
type Responses =
|{ status: 200, data: any }
|{status :301, to: string }
|{status: 400,error: Error }
const response = getResponse()
response // Responses
switch(response.status) {
case 200: return response.data
case 301: return redirect(response.to)
case 400: return response.error
}
字面量型別(literal type)
字面量型別指的是使用字面量語法來定義的型別。字面量型別是一種特殊的型別,它允許你使用字面量值來定義型別的約束。
字面量型別包括以下幾種:
- 數字字面量型別:使用數字字面量來定義數字型別的約束。例如,0、1、2 等。
- 字串字面量型別:使用字串字面量來定義字串型別的約束。例如,"hello"、"world" 等。
- 布林字面量型別:使用布林字面量 true 和 false 來定義布林型別的約束。
- 元組字面量型別:使用元組字面量 [item1, item2, ...] 來定義元組型別的約束。例如,[1, "hello"] 表示一個包含一個數字和一個字串的元組。
- null 和 undefined 字面量型別:使用 null 和 undefined 字面量來表示 null 和 undefined 型別的約束。
- 空型別字面量:使用 {} 來定義一個空型別的約束,表示該型別沒有任何屬性或方法。
- 任意值字面量型別:使用 any 關鍵字來定義任意值的約束,表示該型別可以接受任何型別的值。
編譯器在編譯期間進行型別檢查,提高程式碼的可讀性和可維護性。
通常字面量型別不會單獨出現,而是配合聯合型別,用於約束型別的值
declare function handleRequest(url: string, method: "GET" | "POST"): void;
handleRequest(req.url, "GET"); //編譯透過
handleRequest(req.url, "MYGET"); //編譯不透過,值不合法
as const 作用
使用“as const”將型別鎖定為其字面量版本
在 TypeScript 中,as const 用來明確告訴 TypeScript 編譯器這個變數是隻讀的(const),並且它的型別是字面量型別
還是剛剛的例子
declare function handleRequest(url: string, method: "GET" | "POST"): void;
const req = { url: "https://example.com", method: "GET" };
handleRequest(req.url, req.method);
編譯器會報錯
原因是req型別被識別為
const req = { url: "https://example.com", method: "GET" } as const;
當加上“as const”識別為字面量版本的型別
-本章完-