昨天微軟TypeScript宣佈釋出TypeScript 4.0版本。作為一個大版本釋出,大家一定很關心其帶來的變化和改善。請和蟲蟲一起探索。
概述
TypeScript 是現代JavaScript生態圈核心部分,是有程式設計師大神,安德斯.哈爾斯伯格,在繼Delphi,J++,.net和C++之後又一個語言。是微軟奉獻給開源社群的神器之一。在npm上,在上個月,2020年7月TypeScript首次突破了每月超過5000萬的下載量。
StackOverflow的最新開發人員調查中,TypeScript定位為第二受歡迎的語言(第一是Rust)。
在最新的JS調查狀況中,大約89%的使用TypeScript的開發人員表示會再次使用它。
TypeScript是一種透過新增靜態型別的語法在JavaScript之上構建的語言。這個想法是,透過記下值的型別以及它們的使用位置,可以使用TypeScript對程式碼進行型別檢查,並在執行程式碼之前(甚至在儲存檔案之前)獲得有關錯誤的資訊。還可以使用TypeScript編譯器從程式碼中剝離型別,並提供可在任何地方執行的簡潔易讀的JavaScript。
除了檢查之外,TypeScript還使用靜態型別來支援強大的編輯器工具,例如自動完成,程式碼導航,重構等。在Visual Studio Code或Visual Studio等編輯器中使用過JavaScript,那麼已經在使用由型別和TypeScript提供支援的體驗。
大版本變化總結
自從3.0開始TS發生了很多變化,首先TypeScript 3.0本身帶來大量改善,統一元組型別和引數列表是一大亮點,可在函式上啟用大量現有的JavaScript模式。該發行版還提供了專案參考,以幫助擴充套件,組織和共享程式碼庫。產生重大影響的一個小變化是3.0引入了型別安全的替代,any稱為unknown。
TypeScript 3.1擴充套件了對映型別的功能以處理元組和陣列型別,並極大地簡化了將屬性附加到函式的過程,而無需訴諸於已失效的TypeScript特定執行時功能。
TypeScript 3.2 允許泛型型別的物件,並透過嚴格的輸入leveraged 3.0,以更好的模型超程式設計與功能bind,call以及apply相結合。
TypeScript 3.3在3.2之後遵循一些穩定性,但是在使用聯合型別方法時還帶來了生活質量的改進,並在模式下增加了檔案增量構建。--build
TypeScript 3.4,進一步傾向於支援功能模式,更好地支援不可變資料結構,並改進了對高階通用函式的推斷。最大的亮點是引入了flag,它是一種避免每次執行TypeScript都完全重建而無需專案引用的方法,從而可以更快地進行編譯和型別檢查。--incremental
TypeScript 3.5和3.6,加強了一些型別系統規則,以及更智慧的相容性檢查規則。
TypeScript 3.7是一個非常值得關注的版本,因為它具有新型別系統功能與ECMAScript功能的豐富結合。在型別系統方面,引入了遞迴類型別名引用和對斷言樣式函式的支援,這兩者都是獨特的型別系統功能。從JavaScript來看,該版本帶來了可選的連結和合並功能,這是TypeScript和JavaScript使用者最迫切的兩項功能。
,3.8和3.9帶來了僅型別的匯入/匯出,以及ECMAScript功能,例如私有欄位,await模組中的頂層以及新語法。這些版本還提供了效能和可伸縮性最佳化。
4.0新功能概述
如果已經在專案中使用TypeScript,則可以透過NuGet獲取它,也可以透過以下命令使用npm:
也可以通通VS 2019/2017和VSC版本內建獲得。
可變引數元組型別
想象JavaScript中的一個函式,該函式concat採用兩個陣列或元組型別並將它們連線在一起以建立一個新陣列。
還有tail,它接受一個數組或元組,並返回除第一個元素外的所有元素。
如何在TypeScript中鍵入其中一個?
對於concat,在較舊版本的語言中唯一可以做的就是編寫過載。
第二個陣列始終為空時的七個過載。arr2有一個引數的情況:
很明顯,這已經變得不合理了。不幸的是,鍵入像這樣的函式也會遇到tail同樣的問題。
還有另外一種情況,被稱為"一千個過載死亡",它甚至不能解決一般問題。它只為想寫的過載給出正確的型別。如果想做一個包羅永珍的案例,則需要像下面這樣的過載:
但是,使用元組時,該簽名不會對輸入的長度或元素的順序進行任何編碼。
TypeScript 4.0帶來了兩個基本改善,並在推理方面進行了改進,使鍵入這些內容成為可能。
第一個變化是元組型別語法中的傳播現在可以通用。這樣即使不知道要操作的實際型別,也可以表示元組和陣列的高階操作。當在這些元組型別中例項化通用擴充套件時(或用實型替換),它們可以產生其他陣列和元組型別集。
例如,可以在TS 4.0中鍵入像這樣的函式tail,而不會出現"一千個過載死亡"的問題。
第二個變化是,其餘元素可以出現在元組中的任何位置,而不僅僅是在結尾。
之前,TypeScript會發出如下錯誤:
A rest element must be last in a tuple type.
TypeScript 4.0可以放寬此限制。
請注意,在沒有已知長度的型別的情況下,結果型別也將變得不受限制,並且所有以下所有元素都將成為結果其餘元素型別。
透過將這兩種功能結合在一起,就可以很便捷的編寫一個型別正確的簽名
儘管一個簽名仍然有些冗長,但這只是一個簽名,不必重複,它可以在所有陣列和元組上提供可預測的行為。
功能本身很棒,但在更復雜的場景中也很有用。例如,函式partialCall的部分應用名為的引數。partialCall帶有一個函式f以及幾個初始的期望引數,返回一個新函式,該函式接受f仍需要的任何其他引數,並f在接收到它們時進行呼叫。
TS 4.0改進了rest引數和rest tuple元素的推斷過程,使其"正常工作":
partialCall瞭解其初始可以使用和不能使用的引數,並返回可以接受和拒絕的函式。
可變引數元組型別啟用了許多新的令人興奮的模式,尤其是在函式組成方面,可以利用它來做更好的工作,以檢查JavaScript的內建bind方法的型別。
元組元素標籤
改善元組型別和引數列表非常重要,圍繞常見的JavaScript習慣用法進行強型別驗證。實際上只是對引數列表進行切片和切塊並將它們傳遞給其他函式。可以使用元組型別作rest引數的想法很有意義。
例如,以下使用元組型別作為引數的函式
差異有:可讀性。在第一個示例中,沒有第一個和第二個元素的引數名稱。儘管這些對型別檢查沒有影響,但元組位置上缺少標籤會使其更難使用,難以傳達意圖。
這就是為什麼要在TypeScript 4.0中,元組型別需要提供標籤了。
為了加深引數列表和元組型別之間的聯絡,其餘元素和可選元素的語法與引數列表的語法相同。
使用帶標籤的元組時有一些規則。例如,當標記一個元組元素時,還必須標記該元組中的所有其他元素。
值得注意的是,標籤不需要在解構時以不同的方式命名變數。它們純粹是那裡的文件和工具。
總的來說,帶標籤的元組在利用元組和引數列表周圍的模式以及以型別安全的方式實現過載時很方便。實際上,TypeScript的編輯器支援會在可能的情況下嘗試將它們顯示為過載。
建構函式的類屬性推斷
當noImplicitAny啟用時,TypeScript 4.0可以使用控制流分析來確定類中的屬性型別。
如果並非將建構函式的所有路徑都分配給例項成員,則該屬性可能被認為是undefined。
短路分配運算子
JavaScript和許多其他語言一樣支援一組稱為複合賦值運算子的運算子。複合賦值運算子將一個運算子應用於兩個引數,然後將結果賦給左側。比如:
JavaScript中的許多運算子都有對應的賦值運算子!但是仍然存在三個值得注意的例外運算子:邏輯和(&&),邏輯或(||)和無效合併(??)。
TS 4.0新引入一個新的ECMAScript功能新增三個新的賦值運算子:&&=,||=,和??=。
這些運算子非常適合替換使用者可能編寫如下程式碼的任何示例:
甚至一些模式支援惰性初始化,只有在需要它們時才載入。
在極少數情況下使用帶有副作用的getter或setter時,值得注意的是這些運算子僅在必要時執行賦值。從這個意義上講,不僅運算子的右側"短路"了,賦值本身也是如此。
catch語句中繫結unknown
自TypeScript誕生以來,catch子句變數始終為any。TypeScript允許對它們進行任何操作。
如果試圖防止在錯誤處理程式碼中發生更多錯誤,則上面的程式碼會有一些不良行為!因為這些變數any預設情況下具有型別,所以它們缺少型別安全性,這些型別安全性可能在無效操作上出錯。
TypeScript 4.0允許指定catch子句變數的型別unknown。unknown比any它更安全,在對值進行運算之前,需要執行某種型別檢查。
儘管catch預設情況下變數的型別不會更改,但將來可能會考慮使用新的模式標誌,以便使用者可以選擇這種行為。同時,應該可以編寫lint規則來強制變數具有或的顯式註釋。
定製JSX工廠
使用JSX時,片段是JSX元素的一種,它允許返回多個子元素。大多數鼓勵使用JSX和支援片段的其他庫都具有類似的API形狀。
TypeScript 4.0中,使用者可以透過新jsxFragmentFactory選項來自定義片段工廠。
例如,下面程式碼實現和React相容的方式轉換JSX,但將每個工廠呼叫切換為而不是,並使用代替。
如果需要基於每個檔案使用不同的JSX,則可以利用新的/** @jsxFrag */註釋。例如,
build模式下的速度改進--noEmitOnError
以前,使用該標誌時,在先前編譯時出現錯誤而導致的程式之後編譯程式將非常慢。這是因為來自上一次編譯的任何資訊都不會基於該標誌被快取在檔案中。--incremental--noEmitOnError.tsbuildinfo--noEmitOnError
TypeScript 4.0對此進行了更改,從而在這些情況下極大地提高了速度,並進而改善了模式情況(這意味著和)。
--incremental與--noEmit
TypeScript 4.0允許在利用編譯時使用該標誌。以前不允許這樣做。但是,啟用更快的增量構建的用例足夠重要,可以為所有使用者啟用。
編輯器改進
TypeScript編譯器不僅可以為大多數主要編輯器提供TypeScript本身的編輯體驗,還可以為Visual Studio系列編輯器等提供JavaScript體驗。根據編輯器,在編輯器中使用新的TypeScript/JavaScript功能會有所不同,但是
Visual Studio Code支援選擇不同版本的TypeScript。另外,還有JavaScript /TypeScript Nightly Extension可以保持最新發展(通常非常穩定)。
Visual Studio 2017/2019具有上述SDK安裝程式和MSBuild安裝程式。
轉換為可選連結
可選連結是一項新功能,受到了廣泛的歡迎。這就是為什麼TypeScript 4.0帶來了新的重構來轉換常見模式以利用可選連結和無效合併的原因!
Converting a && a.b.c && a.b.c.d.e.f() to a?.b.c?.d.e.f.(), image
請記住,儘管由於JavaScript中真實性/虛假性的微妙之處,這種重構不能完美地捕獲相同的行為,但它應該捕獲大多數用例的意圖,尤其是當TypeScript對型別有更精確的瞭解時。
/** @deprecated */支援
TypeScript的編輯支援現在可以識別使用/** @deprecated *JSDoc註釋標記的宣告。該資訊顯示在完成列表中,並作為編輯器可以特別處理的建議診斷。在VS Code這樣的編輯器中,不建議使用的值通常顯示為"觸擊式"樣式。
啟動時的部分語義模式
在大型專案中程式構建的過程從初始的一組根檔案開始,進行解析,查詢其依賴項,解析這些依賴項,查詢那些依賴項的依賴項,等等。專案越大,獲得基本的編輯器操作(如轉到定義或快速資訊)的時間就越長。
編輯器可以執行輕量級的部分伺服器,該伺服器僅檢視編輯器已開啟的當前檔案。
很難確切地說出將看到什麼樣的改進,但有趣的是,TypeScript在Visual Studio Code程式碼庫上變得完全響應之前,通常需要20秒到一分鐘的時間。相比之下,新的部分語義模式似乎將延遲降低了幾秒鐘。
在特別大的程式碼庫上重新啟動兩個編輯器時,帶有TypeScript 3.9的編輯器根本無法提供完成功能或快速資訊。另一方面,儘管在後臺載入了整個專案,但具有TypeScript 4.0的編輯器可以立即為正在編輯的當前檔案提供豐富的體驗。
當前,唯一支援此模式的編輯器是Visual Studio Code,Visual Studio Code Insiders中將對UX進行一些改進。
更智慧的自動匯入
自動匯入是一個了不起的功能,它使編碼變得容易得多。之前自動匯入對用TypeScript編寫的依賴項不起作用。需要在專案的其他位置至少寫了一個明確的匯入。
為什麼自動匯入適用於@types軟體包,但不適用於運送自己型別的軟體包?事實證明,自動匯入僅適用於專案已包含的軟體包。由於TypeScript具有一些古怪的預設值,這些預設值會自動將軟體包新增到專案中,因此這些軟體包將被自動匯入。另一方面,其他軟體包被排除在外,因為在所有軟體包中進行爬網確實非常昂貴
當嘗試自動匯入剛剛安裝但尚未使用的某些內容時,所有這些都會導致非常糟TS4.0現在確實在編輯情景一些額外的工作,包括已經在你列出的軟體包的(和)領域。這些包中的資訊僅用於改進自動匯入,不會更改型別檢查等其他內容。能夠為所有具有型別的依賴項提供自動匯入,而不會產生完整搜尋的費用。
在極少數情況下,當列出尚未匯入的十多個型別化依賴項時,此功能會自動禁用自身,以防止緩慢的專案載入。要強制功能正常執行或完全禁用它,應該能夠配置編輯器。對於Visual Studio Code,這是"包含包JSON自動匯入"(或)設定。
新站點
TypeScript網站最近被徹底重寫並推出!