TypeScript 作為一個基於 JavaScript 的超集,通過引入靜態類型檢查,為我們的代碼帶來了可預測性和更高的可維護性。而在很多情況下,由於我們對於某個變量或者表達式的類型進行了精確定義並不等於它在運行時總是符合這個類型。因此,`TypeScript` 允許我們使用斷言(Assertion)來確定一個變量的實際類型。本文將從多個方面探討 `TypeScript` 中的斷言,讓我們一步一步進行深入了解。
一、產生原因
在日常的開發過程中,我們時常遇到一些特殊的情況,比如:
- 我們需要調用一個不規範的 API,它返回的類型並不符合我們的預期;
- 我們希望針對某個變量強制修改類型;
- 我們需要在運行時臨時將某個變量指定為特定的類型。
如果沒有斷言的話,我們可能需要修改當前變量的類型定義,或者編寫多個條件判斷分支,這些都會使代碼顯得繁瑣且難以維護。因此,`TypeScript` 中的斷言功能對於我們解決這些問題非常有幫助。
二、語法
斷言符號可以用作參數和變量,以指定其類型。一般而言,斷言符號 as 用於類型斷言。
const value: unknown = "Hello World!";
const message: string = (value as string).toUpperCase();
console.log(message);
上面的代碼表示我們知道變量 `value` 實際上就是一個字符串,並通過 `as` 操作符對其進行強制轉換,然後將其轉換為大寫並賦值給 `message` 變量。
還有一種類型斷言操作符為 angle-bracket,即用 “ 符號括起來的強制類型轉換,如下例:
const value: unknown = "Hello TypeScript!";
const message: string = <string>value.toUpperCase();
console.log(message);
但是在 `JSX` 語法中,`angle-bracket` 的括法容易使得代碼結構混亂,因此使用 `as` 操作符更為方便和美觀。
三、類型推斷中的斷言
TypeScript 中的類型推斷十分強大,但是有些時候由於我們沒有對某個變量進行類型限制,編譯器會默認它採用 `type any`。因此,在這種情況下,我們需要使用類型斷言來明確告訴編譯器變量的實際類型。比如:
let value = "Hello!";
let reversedValue = value.split("").reverse().join("");
console.log(reversedValue);
代碼中的 `reversedValue` 變量的類型是 `any`。由於類型推斷器並不能準確地知道 `split`和 `reverse` 等方法的返回類型,因此它不會對類型進行強制限制。為了明確表示這個變量的類型,我們可以使用類型斷言,把它轉換為字符串類型。
let value = "Hello!";
let reversedValue = (value as string).split("").reverse().join("");
console.log(reversedValue);
我們使用 `as string` 將當前變量的類型從 `any` 修改為 `string`,這時代碼的類型就可以得到編譯器的準確推斷,以免出現運行時錯誤。
四、類型守衛與斷言聯合使用
有時,我們需要在運行時進行一些類型檢查,這個時候類型守衛就上場了。類型守衛就是一段邏輯用來判斷類型是否為指定類型,可以通過類型守衛改變變量的類型或值。
例如下面的代碼,`value` 是一個 `unknown` 類型的變量,使用類型守衛可以在不修改變量類型的情況下進行安全操作。
function getType(value: unknown): string {
if (typeof value === "string") {
return "string";
}
if (typeof value === "number") {
return "number";
}
if (typeof value === "boolean") {
return "boolean";
}
if (typeof value === "object") {
return "object";
}
if (typeof value === "function") {
return "function";
}
return "";
}
const value: unknown = "Hello!";
console.log(getType(value)); // 輸出:string
我們使用 `typeof` 操作符進行類型守衛,如果變量類型符合 `string`、`number`、`boolean`、`object`、`function` 中的一種,就返回相應的字符串,否則返回空。這樣,我們不需要進行類型轉換和斷言操作,就可以得到變量的正確類型。
有時,類型守衛會與類型斷言一起使用,以提高代碼的可讀性和可維護性。例如:
function getType(value: any): string {
if (Array.isArray(value)) {
return "array";
}
if (typeof value === "string" && value.length > 0) {
return "string";
}
if (typeof value === "object" && value !== null) {
return "object";
}
return "";
}
const value: unknown = "Hello TypeScript!";
const reversedValue = (getType(value) === "string")
? (value as string).split("").reverse().join("")
: "";
console.log(reversedValue);
我們使用 `getType` 方法來判斷變量的類型,如果類型符合 `string`,就進行類型斷言,否則賦一個空字符串給 `reversedValue` 變量。這樣,代碼結構清晰,易於閱讀。
五、`as const` 的作用
我們可以使用 `as const` 或 “ 提示 TypeScript,這個對象不應該變為 mutable(可變的)。
const myObj = {
name: "TypeScript",
version: "4.4.3",
} as const;
myObj.version = "4.5.0"; // 報錯
當我們將 `as const` 添加到對象後,該對象中的屬性將被推斷為只讀,這意味着在編譯時和運行時均不能更改對象屬性的值。這樣可以提高代碼的可維護性並降低出錯的機會。
六、結論
在開發 TypeScript 應用的過程中,我們時常需要進行類型檢查和轉換。`TypeScript` 提供了強大的類型推斷功能,但是有時會產生冗餘的代碼或無法準確推斷某個變量的類型。這個時候,我們可以使用斷言技術來強制指定變量的類型,並準確執行類型檢查。
本文介紹了 TypeScript 中的斷言、類型守衛、`as const` 幾種技術,旨在幫助讀者更好地理解和掌握 TypeScript,提高代碼質量和可維護性。
原創文章,作者:ZUSLT,如若轉載,請註明出處:https://www.506064.com/zh-hk/n/371114.html