Type assertion

TypeScript 筆記 – Type Assertion(型別斷言)

Type assertion 用來告訴 TypeScript 某個 value 或 variable 是某個更具體的型別。

語法:

// 語法一
value as type
// 語法二
<type>value

1. 使用時機

1.1 Union Type

有時候我們會指定某個 variable 為 union type,也就是某個 variable 的 type 可能不只一種,ex: 以下範例中的 id

function printId(id: number | string) {
  console.log("Your ID is: " + id);
}
// OK
printId(101);
// OK
printId("202");
// Error
printId({ myID: 22342 });

但在 TypeScript 中,如果 variable 為 union type,那就只能執行使用所有 union type 共有的 function:

function printId(id: number | string) {
  console.log(id.toUpperCase());
// Property 'toUpperCase' does not exist on type 'string | number'.
//   Property 'toUpperCase' does not exist on type 'number'.
}

因為 idnumberstring,所以只能執行 numberstring 共有的 function,toUpperCase 只存在於 string,所以 TypeScript 會噴錯

但假設你可以確定某些情況下變數的型別,那就可以使用 type assertion 來告訴 TypeScript 該情況下這個變數的型別是什麼,ex:

function printId(id: number | string) {
// 可以用 id as string 告訴 TypeScript id 在這裡的 type 是 string
// 這樣在這裡 TypeScript 就會將 id 視為 string 了
  console.log((id as string).toUpperCase());
}

1.2 Type 不夠明確時

TypeScript 有時候會自動判斷型別,但可能只是比較 general 的型別,ex:

const element = document.getElementById("main_canvas")

TypeScript 會將 element 的 type 判斷為 Element ,但身為定義 id 的人,我們清楚知道這個 id 對應到的一定會是 canvas element,那就可以將這個 value type assertion 成 HTMLCanvasElement

const myCanvas = document.getElementById("main_canvas") as HTMLCanvasElement
// 也可以寫成這樣
const myCanvas = <HTMLCanvasElement>document.getElementById("main_canvas")

2. 可能的問題

TypeScript 會噴錯一定有他的原因,以 union type 為例,只能執行所有 union type 共有的 property 或 function 就是因為如果該 property 或 function 不存在於某個 type 的話,一但 value 是以該 type 傳進來的話,就會噴錯,舉剛剛的例子:

function printId(id: number | string) {
  console.log((id as string).toUpperCase());
}

雖然我們將 id type assertion 成了 string,但一旦有地方執行 printId 傳的是 number 的 argument 進來,那在執行 printId 時就會噴錯。

因此除非你很確定這個 value 在某種情況下的 type,否則不要隨便使用 type assertion。

3. 參考資料

型別斷言| TypeScript 新手指南
Documentation – Everyday Types

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top