iT邦幫忙

2023 iThome 鐵人賽

DAY 29
0
自我挑戰組

Rayeee 的 TypeScript 的學習日記系列 第 29

<20230930> Day 29. 補充水分 Union Types & Type Guard

  • 分享至 

  • xImage
  •  

今天來補充一下關於 聯合型別 & 型別守衛

今日重點

  • Union Types
  • Type Guard

聯合型別 (Union Types)

在 TypeScript 中,可以使用 Union Types 來表示一個變數的型別可以是不同型別組合而成,關鍵字為 | (JavaScript 中的 || 或者)

舉例:
現在有一個 function processInput,功能是預先處理一個 input 中輸入的值
如果傳入的是字串,就轉成大寫,如果傳入的是數字,就最多取到後兩位

function processInput(input: string | number): void {
  console.log(input.toUpperCase()); // 如果是字串,轉換為大寫
  console.log(input.toFixed(2));   // 如果是數字,取小數點後兩位
}

processInput("hello");  // 希望輸出: HELLO
processInput(3.14159);  // 希望輸出: 3.14

input 參數的型別就是聯合型別 Union Types

但是上面這種寫法會有問題,傳入的參數如果是 type string,那對參數使用 input.toFixed(2) 就會壞掉,因為 type string 本身並沒有 toFixed 方法

如下圖,TypeScript 會報錯

https://ithelp.ithome.com.tw/upload/images/20230930/20162544t3sP3EW6IW.png

這個會報錯的原因是因為 Union Types 聯合型別只允許訪問共用的屬性或方法

下圖舉出一些 Type string 和 Type number 能訪問的屬性及方法

https://ithelp.ithome.com.tw/upload/images/20230930/201625440JdIAQVoTZ.png

像是我們範例中的 string | number Union Types,TypeScript 檢查後會發現圖中可用的方法都不是共用的,所以會不允許訪問

https://ithelp.ithome.com.tw/upload/images/20230930/20162544Zi5jqN20bZ.png

要解決這個問題,我們可以使用 Type Guards 型別保護

型別守衛 (Type Guard)

Type Guards 型別保護、型別守衛、型別守衛,我覺得型別守衛比較酷,所以我會稱呼它為型別守衛

在 TypeScript 中,Type Guards 是一種機制,用於在運行時檢查變數的型別。這可以幫助開發者在程式中進行更安全的型別操作。

function processInput(input: string | number): void {
  // 使用 typeof 進行 type guards 檢查
  if (typeof input === 'string') {
      console.log(input.toUpperCase());
  } 
  if (typeof input === 'number') {
      console.log(input.toFixed(2));
  }
}


processInput("hello");  // 希望輸出: HELLO
processInput(3.14159);  // 希望輸出: 3.14

可以看到,錯誤消失了
Type Guards 告訴 TypeScript 參數 input 在使用時的明確的型別,錯誤就消失了

https://ithelp.ithome.com.tw/upload/images/20230930/20162544cBtebT5SLS.png

這就是 Type Guards 型別守衛,可以補充一下要定義每一種 Type 的寫法會略有不同:

https://ithelp.ithome.com.tw/upload/images/20230930/20162544Urji2bdnb3.png

  if (typeof input === 'string') {
    // 
  }
  if (typeof input === 'number') {
    //
  } 
  if (typeof input === 'boolean') {
    //
  } 
  if (input instanceof Array) {
    //
  } 
  if (input instanceof User) {
    //
  } 

參考資料

官方文件 - union-types

官方文件 - Narrowing

[TS] Type Guard and Narrowing


上一篇
<20230929> Day 28. 中秋節快樂
下一篇
<20231001> Day 30. Final 完賽
系列文
Rayeee 的 TypeScript 的學習日記30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言