深入了解 TypeScript 斷言

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

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
ZUSLT的頭像ZUSLT
上一篇 2025-04-23 00:48
下一篇 2025-04-23 00:48

相關推薦

  • Python常用斷言函數用法介紹

    本文將詳細介紹Python中常用的斷言函數,讓大家了解這些函數的作用及使用方法,以便於進行代碼測試和調試。 一、assertEqual函數 1、assertEqual函數是Pyth…

    編程 2025-04-27
  • 深入解析Vue3 defineExpose

    Vue 3在開發過程中引入了新的API `defineExpose`。在以前的版本中,我們經常使用 `$attrs` 和` $listeners` 實現父組件與子組件之間的通信,但…

    編程 2025-04-25
  • 深入理解byte轉int

    一、位元組與比特 在討論byte轉int之前,我們需要了解位元組和比特的概念。位元組是計算機存儲單位的一種,通常表示8個比特(bit),即1位元組=8比特。比特是計算機中最小的數據單位,是…

    編程 2025-04-25
  • 深入理解Flutter StreamBuilder

    一、什麼是Flutter StreamBuilder? Flutter StreamBuilder是Flutter框架中的一個內置小部件,它可以監測數據流(Stream)中數據的變…

    編程 2025-04-25
  • 深入探討OpenCV版本

    OpenCV是一個用於計算機視覺應用程序的開源庫。它是由英特爾公司創建的,現已由Willow Garage管理。OpenCV旨在提供一個易於使用的計算機視覺和機器學習基礎架構,以實…

    編程 2025-04-25
  • 深入了解scala-maven-plugin

    一、簡介 Scala-maven-plugin 是一個創造和管理 Scala 項目的maven插件,它可以自動生成基本項目結構、依賴配置、Scala文件等。使用它可以使我們專註於代…

    編程 2025-04-25
  • 深入了解LaTeX的腳註(latexfootnote)

    一、基本介紹 LaTeX作為一種排版軟件,具有各種各樣的功能,其中腳註(footnote)是一個十分重要的功能之一。在LaTeX中,腳註是用命令latexfootnote來實現的。…

    編程 2025-04-25
  • 深入了解Python包

    一、包的概念 Python中一個程序就是一個模塊,而一個模塊可以引入另一個模塊,這樣就形成了包。包就是有多個模塊組成的一個大模塊,也可以看做是一個文件夾。包可以有效地組織代碼和數據…

    編程 2025-04-25
  • 深入剖析MapStruct未生成實現類問題

    一、MapStruct簡介 MapStruct是一個Java bean映射器,它通過註解和代碼生成來在Java bean之間轉換成本類代碼,實現類型安全,簡單而不失靈活。 作為一個…

    編程 2025-04-25
  • 深入理解Python字符串r

    一、r字符串的基本概念 r字符串(raw字符串)是指在Python中,以字母r為前綴的字符串。r字符串中的反斜杠(\)不會被轉義,而是被當作普通字符處理,這使得r字符串可以非常方便…

    編程 2025-04-25

發表回復

登錄後才能評論