iT邦幫忙

2022 iThome 鐵人賽

DAY 6
0

前一天我們有提到型別聯集(Union Types),也有提到他帶來的好處跟需要注意的地方,需要使用型別間”共有”的方法,但只要透過型別防衛(Type Guard),我們便能穩當的去使用指定型別的方法,而不用受限於共有的。

我碰到這情境的第一個想法是:「那我的程式碼內,豈不是要一直出現if…else…,或者是switch(條件)?要是TypeScript在compile時能幫我去除掉那些block,倒還算人性化,但要是那些判斷式都留著,整個程式碼看起來不就會很亂嗎?」

初學如我如果有想到這種情境,那些更資深的開發者怎麼可能沒想到這件事呢,我們接下來要講的型別斷言(Type Assertion)便恰巧解決了我的疑慮。

型別斷言(Type Assertion)

(下面這例子取自《TypeScript 邁向專家之路:零基礎 JavaScript 打通 Angular、React 與 Vue.js 前端框架實戰》的7-19頁,並簡化了一些)

function priceConvert(price: number, format: boolean) {
    return format ? `$${price.toFixed(2)}` : price
}

let priceNumber = priceConvert(500, false)
let priceString = priceConvert(500, true)
console.log(priceNumber.toFixed(2))
console.log(priceString.charAt(0))

這段程式碼並不難讀,我們宣告了數字版跟字串版的兩個變數priceNumberpriceString,並且對他們執行數字特有的方法及字串特有的方法。儘管我們這邊並沒有”明確”寫出priceConvert的回傳值型別是什麼,但TypeScript已經能從我們的三元運算子中,推斷出回傳的值是個字串與數字的聯集。

回傳值被推斷出是字串或數字

既然回傳值可能是字串或數字,那我們後來想對priceNumberpriceString進行特定型別的方法,就有可能會出錯。

字串的方法不存在於數字唷

在不特地用上型別防衛的情況下,我們可以使用型別斷言。

let priceNumber = priceConvert(500,false) as number
let priceString = priceConvert(500,true) as string

意思大致上是說:「TypeScript我跟你說,這個priceNumberpriceString是個數字/字串啦,我等等對priceNumberpriceString做各種數字/字串才會做的事,你就睜一隻眼閉一隻眼就好了。」

結果,TypeScript真的不再發出警告訊息了!真是聽話呢(?)

斷言後錯誤便消失了

值得注意的是,這邊下了斷言,不代表我們對這個值進行了任何”強制型別轉換”唷。如果priceNumber的型別是number,但我們卻還是斷言他是string,並在後續的程式碼中對他做了字串才有的方法,就算在畫面上錯誤(紅色波浪底線)消失了,但真正在執行時,由於數字沒有字串的方法,就會報錯。而這種情況是我們不樂見的,畢竟使用TypeScript就是想在compile前抓出錯誤。

讓我們再看個情境,要是我們(不管出於什麼原因)想斷言priceNumber是個boolean呢?

亂斷言會出事的

OKOK,TypeScript噴錯了,它表示:「你要將可能是number或是string的值,斷言成boolean?你一定有什麼地方搞錯了吧?畢竟booleannumberstring並沒有聯集啊!啊如果你真的是故意要這樣做的話,那就先把這個值斷言成unknown吧!」

這邊TypeScript說的「先把他斷言成unknown」,有一點偷吃步的味道在。

let priceNumber = priceConvert(500, false) as unknown as boolean
console.log(priceNumber) //500

也就是,我們先把priceNumber的值斷言成"未知",既然他是未知,他當然可以被斷言是boolean,就跟未知的人生,什麼都有可能發生一樣(?)。剛剛提過,斷言不會進行強制轉型,所以就算我們印出priceNumber,也不會得到true/false,而是得到正確的執行結果500

我自己還不確定到底實際在開發專案時,有什麼情況得用到這招,但既然TypeScript都這樣提示了,或許可以留意一下這個用法(如果讀者你/妳曾使用過,拜託跟我分享一下)。


今天簡單介紹了型別斷言,還提到了unknown,那明天就來講講unknown以及其他特殊一點的型別吧,我們明天見!


上一篇
型別介紹part2!
下一篇
型別介紹part4 - 一些特殊的型別
系列文
你也對開始使用typescript感到無力嗎?我也是 - 30天初探typescript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言