typescript很強大,但是用不好時也會很頭痛,開發遇到類型錯誤的情況不在少數,或許你需要了解類型斷言。使用斷言,簡單來說就是先做好一個假設,使得編譯通過。
我一開始接觸類型斷言時是有點不明白的,后來我了解到原因是 “類型斷言更像是類型的選擇,而不是類型轉換”。我發現不少博客文章里把類型斷言說成了類型轉換,這在最開始給我帶來了一些困擾。
使用類型斷言有兩種方式:
<類型>值 // 或者 值 as 類型
推薦以 as 方式,因為 jsx 這樣的語法中只支持 as 方式。
我們還得知道什么時候來使用類型斷言,但是這個我沒辦法一一列舉出來,主要因為我也沒有很多使用typescript的經驗。但是可以舉一個最直觀的例子:
function func(val: string | number): number { if (val.length) { return val.length } else { return val.toString().length } }
函數的參數 val 是一個聯合類型,在這里的意思是說 val 可以是字符串類型也可以是數值類型。代碼中要返回參數的長度,但是 length 可以是字符串的屬性,而數值是沒有這個屬性的,所以當 val 是數值時,就先用 toSting() 來將數字轉換為字符串再取長度。這樣的邏輯本身沒問題,但是在編譯階段一訪問 val.length 時就報錯了,因為 訪問聯合類型值的屬性時,這個屬性必須是所有可能類型的共有屬性,而length不是共有屬性,val 的類型此時也沒確定,所以編譯不通過。為了通過編譯,此時就可以使用類型斷言了,如下:
function func(val: string | number): number { if ((<string>val).length) { return (<string>val).length } else { return val.toString().length } } 或者 function func(val: string | number): number { if ((val as string).length) { return (val as string).length } else { return val.toString().length } }
例子中,把 val 斷言為了 string類型,此時就可以訪問 length 屬性了。你可能會疑惑如果 val 斷言為了string,那么開始定義的聯合類型是不是失去了它的意義?答案是否定的。我在一開始就說了類型斷言不是類型轉換,而是類型選擇,可以理解為在編譯階段強行把 val 當作 string類型來訪問了。
以上就是我對類型斷言的一些了解,如有不對,歡迎指出。