iT邦幫忙

2023 iThome 鐵人賽

DAY 9
0
Modern Web

用不到 30 天學會基本 TypeScript系列 第 9

任意型別 VS. 未知型別 (any VS. unknown)

  • 分享至 

  • xImage
  •  

anyunknown 是兩個用於處理 型別不確定的情況。雖然它們在某些情境下都可以用來處理不確定的值,但它們的用法和限制有所不同,我們一一來介紹:

any 型別

在前面幾個章節,威爾豬應該或多或少都有提到盡量不要使用 任意型別 (any),因為它可以 儲存任何型別的值,同時 取消了型別檢查。這意味著在使用 any 型別時,TypeScript 將不會對該值進行任何型別的檢查,這樣就和寫 JavaScript 一樣了,還浪費時間寫 TypeScript 幹嘛呢?因此它在一些情況下確實很方便,但同時也可能導致運行時錯誤和型別安全性問題。我們看以下範例:

let anyValue: any = 3;
anyValue = "威爾豬"; // ⭕️ 正確
anyValue = true; // ⭕️ 正確

在上述範例中,我們宣告了一個 anyValue 變數,並將其設置為 any 型別,將不同型別的值賦予給該變數,它完全不挑食都會吃下去,這也代表了失去使用 TypeScript 的意義。

unknown 型別

未知型別 (unknown) 與 any 不同的是,unknown 保留了型別檢查。這意味著在使用 unknown 型別時,我們需要在使用之前 進行型別檢查進行類型斷言,以確保安全的操作。看以下範例:

我們將 unknownValue 分別設置為 any 型別unknown 型別,看會發生什麼?

使用 any 型別:
https://ithelp.ithome.com.tw/upload/images/20230909/20141250nMRpeDnd7I.png

使用 unknown 型別:
https://ithelp.ithome.com.tw/upload/images/20230909/20141250iTwEWJfGAO.png

可以看到使用 any 型別輕鬆過關,而 unknown 型別會跳出警告,我們必須多做一些型別的判斷才能消除這問題。

let unknownValue: unknown = "Hello, TypeScript!";

// 需要進行型別檢查
if (typeof unknownValue === "string") {
  console.log(unknownValue.toUpperCase()); // 輸出: HELLO, TYPESCRIPT!
}

由上面範例可知,unknown 型別 在使用之前需進行 typeof 型別檢查,確保只有當 unknownValue 是字串時才調用 toUpperCase 方法。

我們再看一個使用 斷言 的範例:

const handleValue = (unknownValue: unknown): void => {
  // 強制斷言
  console.log((unknownValue as string).toUpperCase());
};

handleValue("Hello, TypeScript!"); // 輸出: HELLO, TYPESCRIPT!

這個範例是我們強制將 unknown 型別轉成 string 型別,確保它可以使用字串的方法。

選擇和比較

any unknown
方便性 超級方便 方便
使用場景 不知道型別,或為了暫時繞過型別檢查 不確定型別
型別檢查 ⭕️
安全性 較高

所以在開發 TypeScript 項目時,還是應該 優先考慮使用更具體的型別,以確保程式碼的可讀性、可維護性和型別安全性。儘管 any 和 unknown 在某些情況下可能很好用,但我們應該謹慎使用,避免引入潛在的錯誤和不安全性。如果必須使用時 (真的不是偷懶),還是要 避免過度濫用 any 型別,儘量選擇使用 unknown 型別來保留型別檢查,才不會執行後發現自己犯了低級失誤。


上一篇
枚舉 / 列舉 (Enum)
下一篇
斷言(Assertion)
系列文
用不到 30 天學會基本 TypeScript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言