1. 程式人生 > 實用技巧 >吐槽 typescript

吐槽 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,感覺有毒啊