iT邦幫忙

2022 iThome 鐵人賽

DAY 17
0

有一次在寫React的useRef時,需要將ref塞進一個HTML element,但我當時還沒有TypeScript的概念,所以,初始化了一個useRef(null)後,將他塞進一個span,TypeScript就報錯了,害我當下有點不知所措,所以就google了一下相關資訊,才知道,我應該要先註記他會是特定型別,而那個型別叫HTMLSpanElement。今天,我們來簡單講講TypeScript要怎麼用在DOM上面吧。

直接來看個例子:

const anchor = document.querySelector("a")
console.log(anchor.href)

我們都知道第一行要選取html中的(第一個)a tag(如果有的話),第二行要印出那個a tag的hypertext reference。如果這兩行是寫在.ts,且我們有在tsconfig.json開啟strictNullChecks這個flag的話,TypeScript是會報錯的:

Object is possibly 'null'

之所以會這樣,是因為,在寫這幾行code的時,TypeScript不會知道你編譯後的js檔要安插的html檔內,有沒有這樣一個元素,所以TypeScript幫你將anchor這個變數判斷成HTMLAnchorElement | null,表示他可能真的是anchor,也可能是null。

這邊我們可以很簡單的用型別防衛去解決這問題:

if(anchor.href){
    console.log(anchor.href)
}

但還有更優雅的寫法!(在我們先前的文章中都沒提過)

const anchor = document.querySelector("a")! //最後加個驚嘆號

這個用法叫做"非null值斷言法",只有在你確定null值絕不會發生時才可使用。如果你用了以後,但最後null值還是發生了的話,執行時就會噴錯了。所以,比較安全的做法其實是先前的例子:寫個if進行型別防衛。

加上驚嘆號後,TypeScript就不會報錯,你就能繼續編譯了。
這時如果我們打上anchor.,你就能看到一大堆"確定在"a tag能取用的屬性/方法,這種autocomplete超方便的。甚至連已棄用的屬性都能順便列出來給你看。

TypeScript對於你所定義的型別,直接列出相關可用/被棄用的屬性/方法

再來看一下另一個情境,document.querySelector("a")我們都知道這寫法太籠統了,在開發中應該是透過選擇更有說明意義的class、甚至是id,來更精確地選擇到我們要的元素:

const anotherAnchor = document.querySelector(".theanchor")

那這時就有趣了,TypeScript才不會知道.theanchor是什麼鬼,更不會知道他是什麼型別,也就不可能推薦你anotherAnchor可以取用的屬性/方法。所以我們可以對anotherAnchor進行型別斷言。

const anotherAnchor = document.querySelector(".theanchor") as HTMLAnchorElement

便可以解決上述的問題!
既然這邊看到HTMLAnchorElement了,我們就能推論其他相對應的型別會叫做HTMLSpanElement或者HTMLFormElement,我目前沒有仔細查有哪些,但相信要用時再google一定很快。

今天簡單講到這邊,要週一了0rz


上一篇
第16天!泛型Generic Types
下一篇
第18天!TypeScript檔內要怎麼引入JavaScript?
系列文
你也對開始使用typescript感到無力嗎?我也是 - 30天初探typescript30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言