Type assertion 用來告訴 TypeScript 某個 value 或 variable 是某個更具體的型別。
語法:
// 語法一
value as type
// 語法二
<type>value
Table of Contents
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'.
}
因為 id
是 number
或 string
,所以只能執行 number
和 string
共有的 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。