吐槽 typescript
說起 typescript,認識的還蠻早,因為不喜歡強型別,所以並不是很喜歡。但是隨著越來越多的程式設計師使用,慢慢的我也重新審視自己,是不是太井底之蛙了。
所以我最近又重新拾起,一邊閱讀一些優秀的 Typescript 原始碼,一邊編寫小工具 resize-detector,為了鞏固下所學。終於結束了,對比之前我使用 js 直接開發功能,在使用 ts 時候,談下我使用後的一些想法:
首先是環境搭建,說實話真的要看個人,你是喜歡簡單版還是進階版還是完整版,因為我是基於一個開源的第三方庫編寫,自然需要完整。然後我就到處找各種配置,終於配製出適合自己的。不過因為是初版,到現在依舊不是很滿意,但勉強可以使用了。
那麼環境搭建完畢,就要開始寫程式碼了,寫程式碼途中我發現,之前聲明瞭如下的型別:
export type XXX = string | undefined | null
因為我需要使用這種型別,結果無意間看到一個 type,叫做 PropertyKey
,和我這種型別一模一樣,這就很尷尬了,等於我重複定義了一個變數。而這個 PropertyKey
它是個全域性變數,這是內建的。有人可能會說你不會去參考看下 lib.dom 庫啊,可是關鍵如果一個新手來做,他知道這個庫嗎?
這是寫型別遇到的第一個問題:內建型別/介面不知道如何尋找
當然第一個問題對於我來說還是很好解決的,那麼第二個問題就有些複雜,就是我寫了一個公共的回撥函式,在 ts 中因為不同的介面實現都定義了一套自己的回撥型別,結果就是我寫的這個方法不停的在轉化型別(目前也是這麼做的,應該可以優化)。於是我就想到能不能根據誰使用,那麼根據使用者來推斷型別。答案自然是有的,畢竟我是個後來者,在網路上的列子中我知道了 extends
infer
關鍵字,說真的,至少當時我激動了,有解決方案。可以網路上說的真的太基礎,或者官網示例,雖然看了很多,但是說清楚的沒幾個,至於到現在我對這個 infer
只有特定環境才可以明白如何寫,介面就是我依舊沒有找到方法去實現我的想法(有一篇文章 我個人覺著講的還行,因為不是盲目的貼上複製)。這是我遇到的第二個問題:如何編寫高校的檢測型別
遇到的第三個就是關於eslint
,我使用的是ts
團隊自家產品 @typescript-eslint/eslint-plugin
,可以說提示的還不錯,但是每次在寫到js
中的object
型別我就是很糾結,因為推薦我使用Record
型別,我也聽話了,用上後發現一個很尷尬的,我自己定義的option
Record
型別相容,我定義的options
型別就是<string, unknow>
,Record
型別也是Record<string, unknow>
為什麼不行呢,後來我換成了object
型別就可以,就目前而言,關於物件的表示我依舊不是很清楚怎麼寫,是寫Object
,還是object
,還是Record
,雖然eslint
推薦使用Record
,我是真的迷糊了。這只是我舉得一個列子,其實就是想說我遇到的第三個問題:到底應該如何使用合理的型別
那麼第四個問題,我需要向原始物件HTMLElement
新增屬性,但是ts
提示不可以,我也能理解,所以我為了不汙染這個HTMLElement
,我重新聲明瞭一個新的介面(假設是IDomNode
)繼承HTMLElement
,然後我就基於我宣告的新的介面IDomNode
寫,寫到最後都是沒有問題的,釋出完我測試,發現當然呼叫方法傳入HTMLElement
,提示不行,因為HTMLElement
沒有IDomNode
上的一些屬性,關鍵我這個IDomNode
又不是一上來就有,難道我需要自己再寫個方法將每一個HTMLElement
初始化成IDomNode
,最後我先使用了折中辦法,將所有的IDomNode
類的屬性變成可選,這就導致只要是使用到IDomNode
的屬性就必須先判空,雖然我可以肯定他們存在,但是ts
不信他們是存在的。所以我又寫了一堆方法判空,感覺顯得很多餘。
差不多了,其實網上很多評論對比,當然都不及自己去寫寫,使用中出現很多問題,即便到現在釋出了,我也不敢說這是穩定版,只能釋出了一個alpha版本。typescript 正如字面可以很好的檢測型別,但是多數需要自己合理編寫一些檢測型別來推斷。
說真的我覺得還是蠻搞笑,以前直接寫es5
,後來es6
出來了,寫es6
,但是為了照顧老瀏覽器,最後將es6
轉成es5
在編寫,現在是寫typescript
,再轉成es6,感覺有毒啊