作者 | Robert Vitonsky
編譯 | 云中
幾天前,漢森 (David Heinemeier Hansson)宣布 Turbo8 即將放棄 TypeScript。我心想:放棄就放棄吧,反正我也不知道 Turbo 8 是什么鬼。
然而,在過去的幾年里,一些前端程序員試圖向我推銷“ TypeScript 沒用,只測著玩玩”的想法。我認為,有這種觀點的人要么不關心代碼質量,要么根本不知道 TypeScript 是什么。在這里,我將解釋為什么應該使用 TypeScript。
注:本文作者 Vitonsky 是一名超過10年的有著復雜項目的前端大牛,參與了許多開源項目的開發:比如翻譯網站的瀏覽器插件 Linguist、模塊 UI 工具ElegantUI、翻譯 DOM 節點的 DomTranslator 庫等等。
1、代碼質量控制的“好手”
代碼質量控制是一個保持代碼可維護性的復雜過程。你不能僅僅用 100% 的測試覆蓋代碼,或者審查每個拉取請求并確保你的代碼是可維護的,還應該讓除你之外的其他人也可以識別并搞定它。
根本無法保證自己的代碼沒有 bug 的同時具有完美的可維護性。你只能在存儲庫中增加防御結構,以使其難以推送帶有錯誤的“炸彈”代碼。阻止“炸彈”代碼的障礙越多,代碼質量就越好。
這意味著你應該一起使用所有方法來保護存儲庫中的代碼:單元/e2e/集成測試、代碼審查、代碼分析工具以及維護清晰的文檔等。
TypeScript 是一個強大的代碼分析工具;它可以檢測代碼中的許多缺陷。TypeScript 編譯器迫使程序員確保代碼在類型級別上是正確的。David 和許多其他人低估了靜態類型的價值。
讓我們看看 TypeScript 為代碼質量帶來了哪些好處。
2、contract 對代碼的重要性
靜態類型允許在代碼中定義 contract。
type Participant = {
id: string;
name: string;
};
function sayHi(participant: Participant) {
//...
console.log(`Hi ${participant.name}`);
}
該 sayHi 函數需要一個具有精確屬性和精確類型的對象,并且它不關心該函數的用戶將做什么來滿足要求。編譯器確保類型正確。
用戶可能會提供一個不符合要求的對象并將類型強制轉換為 any,但這不是函數 sayHi 的問題。這是一種責任委托,是開發人員必須理解的一個重要概念,才能正確使用 TypeScript 并獲得其好處。
程序員必須驗證任何不受信任的數據,例如用戶輸入和其他 IO 數據,或與 JAVAScript 互操作的結果。驗證和設置類型后,他們可以將數據傳遞給 TypeScript 代碼,并相信合同將得到遵守,因為 TypeScript 編譯器已經檢查了代碼。如果程序員強制轉換類型,他們必須確保代碼在運行時正確。
如果你將項目中的非相交類型轉換為任何非 unknown 的類型(沒有運行時驗證),那么代碼質量可能存在問題。
contract 可以避免為每個函數編寫驗證以確保數據正確。這對于性能和代碼整潔度來說都很好,代碼變得愚蠢而簡單。
3、使用JS造成的不好經驗和成本
有時我會用純 JavaScript 編寫代碼,主要是在瀏覽器控制臺中,以便在網頁上進行快速計算或數據解析。幾個月前,我為 Node.js 編寫了一個使用 ChatGPT 翻譯區域設置文件的腳本。這些文件包含長文本,而 ChatGPT 有限制,因此需要一些時間對文本進行切片、翻譯、在ChatGPT的結果中查找錯誤、根據需要重新翻譯,然后將切片重新連接在一起。根據區域設置文件的大小,此過程大約需要 3-5 分鐘。
在這個過程中,由于一些瑣碎的類型錯誤,我浪費了一些時間,比如忘記使用 wAIt,這導致一個變量包含 Promise,并將“[object Promise]”寫入文件而不是翻譯文本,或者將錯誤的對象作為函數參數提供。
TypeScript 消除了這樣的錯誤。
4、 TS更面向未來
TypeScript 為你的代碼提供了其他工具分析的潛力,因為它添加了上下文。
使用 IDE,你可以重命名接口中的屬性,并且實現該接口的所有實體將自動在各自的位置更新屬性的名稱。
ChatGPT 和 Copilot 等 AI 工具受益于 TypeScript 提供的附加元信息,有可能改進代碼分析和代碼生成。這些分析工具可以更好地識別潛在風險的代碼。
靜態類型和測試相得益彰。前端代碼是高度異步的,這使得覆蓋所有可能的測試用例并考慮所有潛在的代碼狀態,變得非常有挑戰性。TypeScript 迫使程序員處理一個狀態可能具有的所有可能情況,從而增強代碼可靠性。
5、類型:復雜性與質量的取舍
漢森還說道說:
“TypeScript 對我來說只是阻礙。不僅因為它需要顯式的編譯步驟,還因為它用‘類型體操’污染了代碼,這給我的開發體驗增添了很少的樂趣,而且常常帶來相當大的悲傷。應該容易的事情變得困難,而困難的事情變成了‘any’。所以不用了,謝謝!”
確實,有時必須編寫重要的類型,才能讓編譯器相信你的數據是正確的。但事實就是這樣:創建高質量的可維護代碼通常需要付出艱苦的努力。
6、結論:會用的人不會抱怨工具
TypeScript 只是一個工具,如果你簡單地啟用它,它不會自動提高代碼質量。你的項目必須制定正確使用該工具的規則,以及執行這些規則的架構師。規則越嚴格越好。
當在項目中禁用靜態類型時,你將失去許多控制代碼質量的功能。
JS 文檔和 .d.ts 類型聲明文件無法替代代碼的靜態類型。它們只是聲明實體外部 API 的方法,但不允許分析實體內的代碼(函數、類和其他代碼塊)。
原文鏈接:https://vitonsky.NET/blog/2023/09/08/typescript-and-code-quality/