弄了一個持續更新的github筆記,可以去看看,連結地址:Front-End-Basics
此篇文章的地址:使用TypeScript兩年後-值得嗎?
基礎筆記的github地址:github.com/qiqihaobenb… ,可以watch,也可以star。
這是我的第一篇翻譯文章,想看這篇文章的時候,發現沒有中文翻譯版,無奈去讀了英文版,讀完發現可以試試翻譯出來。
本人英語水平不是一般的差,之前很排斥讀英文資料,現在努力轉變觀念,慢慢的開始不那麼害怕讀英文資料了。這篇文章在磕磕絆絆的查單詞中讀了第一遍,然後在不查單詞的情況下順了兩遍,難免肯定會有錯誤,懇請指正。當然你也可以直接讀更準確的英文原文。
正文開始……
作者:Kamil Zagrabski
差不多兩年前,我在一個創業團隊中開始了一個全新的專案。用到的全都是類似Microservices,docker,react,redux這些時髦的東西。
我在前端技術方面積累了一些類似的經驗,因為在更早的一年前我帶著20多名前端開發人員編寫了一個非常大的react應用程式。這對我來說非常具有挑戰性。當時我們遇到了很多問題:模型內聚的問題,程式碼庫的增長,複雜且難以維護的api,介面不一致,難以跟蹤執行時異常。
在開始新專案之前,我決定找到解決這些問題的方法。我想也許我們遇到的這些問題是因為語言本身有點過於靈活和寬泛導致的。你輸入的內容幾乎沒有限制,再加上沒有編譯階段,沒有約束和執行前程式碼驗證,這可能導致你的包存在嚴重錯誤。
然後我接觸到了Flowtype和TypeScript。經過短暫的評估後,我決定選擇TypeScript,並且一直用到現在。在兩年後的今天,我可以告訴你 - 決定使用TypeScript對專案和我的職業生涯來說是個不錯的選擇。但是,如果你認為TypeScript開發人員的生活總是稱心如意的,那麼你最好繼續閱讀。
在本文中,我不想詳細說明TypeScripts的功能或深入專案設定。網際網路上有很多很好的資源(例如官方TS文件:www.typescriptlang.org/docs/home.h…
這是一個關於在使用TypeScript日常工作中感受到的優缺點的總結。我想描述一下我使用TypeScript的最糟糕體驗,另一方面,我也要說一下我認為最有用的功能。所以本文都是關於利弊好壞的權衡,讓我們開始吧。
首先要做的事 - 配置
正如我所提到的,我對react和redux有一些經驗,所以我想利用這些優勢,在新專案中使用類似的(自定義)配置。比如 - webpack,babel,npm scripts,jest,linter這些通用的東西,只需要額外做一件小事 - 支援TypeScript。
如果你現在處於同樣的境遇 - 我確切的告訴你:它不僅僅是在webpack配置中加一個loader。必須為TS提供一個宣告,用TSLint替換ESLint,整合TypeScript的loader和babel的配置,將TS插入Jest(測試平臺)。
一些操蛋的事情馬上就會發生。TS配置並不好搞,“簡單的複製並測試”這種策略並不是上手的最佳方法。
在將tsconfig.json放入專案之前,最好仔細閱讀文件。
此外,Jest(轉換,模組對映器)和css模組存在一些問題。可能你遲早會面對它們。並且不要認為,你現在可以扔掉babel - TypeScript不會提供任何polyfill來讓你使用那些牛批閃閃的新語法和功能,也不會將你的新API轉換為舊瀏覽器可以理解的程式碼。
所以我的建議是 - 如果可以的話,你應該使用一些入門工具或支援TS開箱即用的CLI(比如 angular cli),以避免無休止的專案配置。
類庫支援
另一個非常不愉快的經歷與TypeScript支援的類庫數量有關。
通常,如果你是某個人npm包的作者,你可以隨時使用有效的JavaScript包。有時,您還會公開包的ES6原始碼。如果你準備將庫用於TypeScript,你必須提供型別定義。簡單來說 - 是一個具有每個模組,名稱空間,類,方法,函式等的宣告的檔案,TypeScript使用者需要用到這個。TypeScript模組只能使用定義中描述的內容,並且只能以宣告中指定的方式使用。遺憾的是,通常原始碼和宣告之間沒有嚴格的聯絡。並且它們可能還是不正確或過時的,或者根本就沒有。
就個人而言,我沒有找不到宣告這樣的問題。大多數流行的庫都有自己的作者或社群準備好的型別定義。如果您使用的包沒有這樣的檔案 - 那就換一個,相同功能的npm包多的是。不過你可以搞一個“假的”宣告檔案,或建立一個真實的宣告檔案併發布出來,以此為開源社群做出貢獻。
不管怎樣,還有一個更嚴重的問題 - 正如我之前提到的,一些宣告是不正確的或過時的。如果你遇到這樣的問題,沒有簡單的解決方案。你可以使用宣告能正常工作的之前的版本,自己修復並貢獻出去或等待作者來解決。有時候他們會及時修復,有時候就沒那麼快了。
順便說一句,我是一些簡單包的作者,相信我,即使想做好,但是我還是常常忘記將新功能與其型別定義同步。
日常工作
現在該輪到高興點的部分了。一旦你配置了專案並選擇了具有良好TS支援的庫,就可以體會到型別語言的強大了。如果你沒有這種語言的背景,一開始可能有點奇怪。TypeScript中有許多功能在當前的JavaScript語法中找不到。讓我們談談其中對我來說最有用的那些。
型別
如果大家所想,TS最常用的功能是靜態型別。沒有使用嚴格型別校驗也就沒有使用TypeScript的意義。當然你可以使用寬泛的“any”型別,這意味著“我不關心那個東西的型別,它可能是一個數字,它可能是一個字串陣列,只管用就行了”,嚴肅臉,如果你想用這樣方式編碼,那還不如用回舊的JavaScript。
型別將幫助你更快,更安全地編碼。你可以告訴編譯器“這個常量妥妥的是一個數字”,如果你嘗試將其用作陣列或字串,TS編譯器將始終提示你輸入錯誤。基本上,你仍然可以使用你的程式碼做任何你想做的事情,就像常規JavaScript一樣,但現在你的操作比以前更安全,更易理解。
TypeScript中有幾種基本型別和一點點跟它們相關的高階型別和技術。
下面你可以看到一些基礎的但非常強大的東西,對於更高階的型別,請訪問文件:www.typescriptlang.org/docs/handbo…
除了眾所周知的型別,如數字或字串,TypeScript還提供了列舉型別。
您可以使用內建型別,如Date或Error。嘗試程式碼提示,以實現更快,更安全的程式設計。
介面
如果你認為型別是“顛覆者”,那麼你對介面有什麼看法?介面可以幫助你編寫更好的程式碼,因為它們最終允許你定義物件之間的約定好的實現方式。我建立了很多介面。他們無處不在。有時我專門為介面寫一個檔案,因為這樣是值得的。
我主要用它來描述物件,類,函式和引數的形狀。你可以在模組之間共享它們並像處理原始碼中的例項一樣對待,不過要記住 - 執行時介面不會出現在程式碼裡,這一點很容易忽略。這就是為什麼有些情況下使用類而不是介面(如使用Angular Dependency Injection)更好。讓我們看一下介面的一些真例項子:
在左邊 - 返回型別的錯誤實現。在右側 - VS Code 立即通知你程式碼中的錯誤。
在左側 - 一個類錯誤地實現了使用者擴充套件的介面(參見上一個螢幕)。在右邊 - 描述錯誤資訊..
類
ES6中有類,所以你可能之前用過它。但是在TypeScript類中有一些額外的功能,可能EcmaScript的未來會實現這些功能。在TS中,您可以定義抽象類,你可以將類的屬性描述為靜態,私有或只讀,您可以擴充套件類並使類實現介面(沒毛病)。我不會比較TS類和ES6類之間的差異,因為最終它們都會產生類似的JavaScript程式碼(在編譯和轉換之後)。在TS類中,只是用優雅而有效的方式封裝要使用的類,它們與其他語言實現(如Java)非常相似,這會產生一些影響(更多關於“程式碼審查”部分的內容)。看一下例子就能知道怎麼用TypeScript和優秀的程式碼編輯器配合來讓你的工作更容易。
當然,TypeScript中還有很多新東西,比如泛型(你會使用它們),列舉(對於內部事物可能會用到),名稱空間,JSX支援等等。但你一開始不需要知道的面面俱到,只需使用上面提到的基本功能,你將看到,你的程式碼質量得到了提高。
使用TypeScript,你可以使用抽象類等功能。有關抽象類的更多資訊:www.typescriptlang.org/docs/handbo…
TypeScript支援private,public和protected方法,只讀屬性。類可以實現介面或擴充套件其他類。
程式碼質量
我剛才提到程式碼質量了嗎?當然提到了,因為我們都關心程式碼質量(除此之外還有客戶需求,截止日期和排期,以及...)。
那麼為什麼應該使用TypeScript呢?(在程式碼質量這個層面)
-
程式碼中沒有與引數或變數名的拼寫錯誤相關的一些非常煩人的執行時錯誤
-
您可以建立清晰明瞭的物件之間的約定
-
不用hack的手段就能實現類似在class中使用private的事情
-
有來自編譯器的即時反饋,很多錯誤都是在編譯階段捕獲的,而不是在執行時
-
讓非JS開發人員更容易閱讀和理解程式碼
-
你可以使用JavaScript未來版本中的功能
-
為單元測試編寫mocks,stubs和fakes要容易得多,因為你知道他們的確切介面。
此外,由於出色的IDE支援,編寫可維護程式碼要容易得多。老實說 - 即使你單獨寫一個不大的應用程式,幾周後你也會忘了你必須傳給服務的引數型別或新建立使用者包含什麼樣的資料。你當然可以翻原始碼,過一遍程式碼然後找到有用的資訊(假設你的程式碼總是簡潔的),但在你喜歡的編輯器中將滑鼠hover到函式名上就能看到你要的資訊豈不更好?例如,它接受“age”,這是一個“number”,並返回具有“age”和“name”屬性的使用者例項。
程式碼審查是我想提到的另一件事。當你在小團隊中工作時,有時候你是唯一的前端開發人員,在做.net或Java的同事真的不喜歡看原生的JavaScript。由於語言的動態和簡潔性,他們會覺得可讀性很差,沒有型別意味著沒有提示。例如 - 名稱為“user”的物件具有“ID”屬性,但ID是數字還是字串?如果是一個字串,為什麼你只需要呼叫“toString()”就可以了?如果是一個數字,為什麼你剛剛在它前面新增字串“id_”呢?TypeScript程式碼看起來很像其他流行的型別語言,並且你有可能將獲得更好,更準確的程式碼審查。更好的程式碼審查意味著更好的程式碼,這個不需要我再多說了吧。
左側 - TypeScript中的程式碼。右邊 - Java中的程式碼。如您所見,語法非常相似,這意味著比起原生的JavaScript,Java開發人員應該更容易理解你的TypeScript程式碼。
學習曲線
最後關於TypeScript我還要多說一點。與往常一樣,當你嘗試新事物時,會有一些學習曲線。放到TS下看,它不是非常陡峭,但是要避免TypeScript和新框架一起用,這兩樣加起來就會讓學習曲線變得足夠陡峭。特別是在大型或缺乏經驗的團隊中。這就是為什麼我兩年前選擇了這個專案作為我的第一個TypeScript應用 - 我對react那套技術棧非常熟悉,所以這是一個學習一種有前途的新語言很好的會。我敢保證,如果我同時選擇了一個新框架(比如說Angular)和一種新語言,我會被按在地上摩擦。
總結
我會向你推薦TypeScript嗎?當然會。它將幫助你在更短的時間內寫出更好的程式碼。IDE支援現在非常棒,社群充滿活力,具有TS定義的庫的數量很龐大而且還在不斷增長,用過的程式設計師都說好(來自編譯器的快速反饋)。這是我所知道的用於建立現代和可擴充套件的Web應用程式(當然還有Node.js服務)的最佳工具。請記住上面提到的一些缺點,解決了它們就能深入探索靜態型別語言的多彩世界了。