摘要:使用過 TypeScript 的前端開發者們,大多對 TypeScript 抱有好感,TypeScript 如今在前端領域也佔據核心一隅。然而,在庫開發者的眼裡,TypeScript 似乎就很不「友好」了,本文作者亦是如此認為的。你在使用 TypeScript 時,是否遇到過這些問題呢?
原文連結:https://erock.prose.sh/typescript-terrible-for-library-developers
作者 | Eric Bower
譯者 | 彎月
以下為譯文:
作為一名前端開發人員,我非常喜歡TypeScript。我感覺TypeScript大幅削減了手動編寫自動化測試的需求,減輕了編寫和維護自動化測試的負擔,推動了開發人員生產力的提升。
但是,作為庫開發人員,我非常討厭TypeScript。我認為TypeScript不適合庫開發,其中的原因有很多,但歸根結底還是因為Typescript降低了開發人員的工作效率。實際上,我認為TypeScript將軟體開發的複雜性從前端開發人員轉嫁到了庫開發人員,給每個希望成為TypeScript專家的人帶來了巨大負擔。
文件
TypeScript面向前端開發人員的文件和部落格文章很豐富,但面向庫開發人員的資源卻很少。我所能找到的面向庫開發人員的只有這一段有關類型操作的介紹(https://www.typescriptlang.org/docs/handbook/2/types-from-types.html)。
可能是因為他們認為庫開發人員和前端開發人員並沒有什麼區別,恕我不能贊同。
為什麼TypeScript官網沒有提供任何有關庫開發的指南?也沒有任何推薦給庫開發人員的工具指南?
事實上,TypeScript的應用開發與庫開發之間存在一個巨大的鴻溝。Web應用很少需要條件類型、類型運算子和過載等結構。但庫開發人員需要大量使用這些結構。這些構造是高度動態的,而且會在類型中加入邏輯。這導致我對TypeScript的調試大失所望。
調試
庫開發人員如何調試高度動態且大量使用的條件類型以及負載?調試唯一可用的工具只有TypeScript的編譯器和專業知識。你可以修改程式碼,然後看看類型最終的結果。在我看來,庫開發人員只能憑直覺,除此之外沒有任何更好的解決方案。
據我所知,庫開發人員大量使用的唯一工具就是TypeScript演練場,他們可以在這個環境中將類型的邏輯分離出來,研究TypeScript將類型解析為另一種類型的原因。此外,你還可以在這個環境中輕鬆地修改TypeScript的版本和配置。
如果你知道任何TypeScript的調試工具,請不吝指教,因為我寫這篇文章,不僅僅是為了發牢騷,更希望高人指點迷津。
複雜性
我使用了很長時間的redux,在我看來redux-toolkit是一個很了不起的庫,你可以藉助這個庫查看真實的程式碼庫是如何使用類型的。我必須說明,它們在類型方面的表現非常出色,但複雜度非常驚人。
下面是兩個例子:
- createAction #1:https://github.com/reduxjs/redux-toolkit/blob/4ab8c42cb20ae1e6f7b84a8ac0070eee54775b79/packages/toolkit/src/createAction.ts#L58
- createAction #2:https://github.com/reduxjs/redux-toolkit/blob/4ab8c42cb20ae1e6f7b84a8ac0070eee54775b79/packages/toolkit/src/createAction.ts#L193
這個程式碼庫中充斥著各種複雜類型。請注意類型的數量與實際的程式碼量。我大致統計了一下(忽略匯入的程式碼),該檔案中只有約10%的程式碼轉譯成了js程式碼(js程式碼:35行,程式碼總數:330行)。
風格指南中總是強調,不要使用嵌套的三元運算子。然而,在TypeScript中,你只能通過這種方式根據其他類型來縮小類型的範圍。
測試
由於類型可以根據其他類型生成,而且這些類型高度動態,所以任何嚴肅的TypeScript項目都需要一類新型的測試:測試類型。在最新版本的TypeScript編譯器上測試類型遠遠不夠,你還需要針對以前的版本進行測試。
這類新型的測試還處於起步階段,相關的工具有些已被棄用,而有些處於半維護狀態。我曾使用過的庫如下:
- DefinitelyTyped-tools:https://github.com/microsoft/DefinitelyTyped-tools
- tsd:https://github.com/SamVerschueren/tsd
- dtslint:https://github.com/microsoft/dtslint
- typings-checker(已被棄用):https://github.com/danvk/typings-checker
該領域的人才大量流失,我的一些項目至今仍在使用已棄用的庫,因為遷移程式碼會非常痛苦。
值得推薦的工具似乎只有兩個:dtslint 和 tsd。為什麼我們需要兩個工具來完成大致相同的工作?這一點很令人迷惑。
維護
類型導致程式碼量急劇增加。當第一次嘗試為項目貢獻程式碼時,你必須了解應用程序的邏輯以及類型的邏輯。這會導致我們的心理壓力增加,同時還會導致程式碼量急劇增加。舉個例子,我在幫忙維護redux-saga,最近大多數的拉取請求和議題都是與類型相關的。
我花費在調整類型上的時間遠遠超過了編寫庫的程式碼。
雖然我很熟悉TypeScript,但我並不是專家。雖然我花費了數年時間編寫TypeScript程式碼,但作為庫開發人員,我仍然沒有足夠的知識來使用TypeScript,這讓我倍感沮喪。精通語言似乎是一個先決條件。類型使得維護js庫的難度加劇,為這些庫貢獻程式碼更是難上加難。
總結
我很喜歡TypeScript,而且我也同意TypeScript對前端開發有很大的幫助。TypeScript徹底改變了前端開發的格局,我們無法忽視它帶來的巨大影響。
但作為庫開發人員,我們需要:
- 更好的文件;
- 更好的工具;
- 減少花在討tsc歡心的時間。
我只不過是為了弄清楚為什麼TypeScript將一段程式碼解析為特定類型,也不至於要求我閱讀TypeScript編譯器的源程式碼吧?