天天看點

TypeScript 5.3 初探,有你想要的功能嗎?

作者:CSDN
TypeScript 5.3 初探,有你想要的功能嗎?

【CSDN 編者按】本文所提到的這些功能,你最希望哪個能實作。

原文連結:https://www.totaltypescript.com/typescript-5-3

作者 | Matt Pocock 翻譯 | ChatGPT 責編 | 夢依丹出品 | CSDN(ID:CSDNnews)

8月24日,TypeScript 進階項目經理 Daniel Rosenwasser 在官博釋出 TypeScript 5.2 版本,該版本進行了多項功能更新,添加了對 ECMAScript 中即将推出的顯式資源管理功能支援、推出了裝飾器中繼資料(Decorator Metadata),可以讓裝飾器輕松地在其使用的任何類上建立和使用中繼資料、命名和匿名元組元素,Tuple 類型支援為每個元素提供可選的标簽或名稱等。

與此同時,官方團隊還宣布了 TypeScript 5.3 疊代計劃,該計劃是用來規劃5.3 版本可能包含的功能,本文作者總結了一些開發者最感興趣的功能。一起看下。

TypeScript 5.3 初探,有你想要的功能嗎?
TypeScript 5.3 初探,有你想要的功能嗎?

導入屬性(Import Attributes)

TypeScript 5.3 很可能會新增導入屬性,該功能已經達到 Stage 3 的 TC39 提案。該功能允許開發者導入指定選項,例如,你可以指定 JSON 導入類型:

import json from './foo.json' with { type: 'json' };           

它還支援你指定動态導入的類型:

import("foo.json", { with: { type: "json" } });           

還可以使用經過驗證的類型重新導出一個子產品:

export { val } from './foo.js' with { type: "javascript" };           

或者使用經過驗證的類型執行個體化 worker:

new Worker("foo.wasm", {              type: "module",              with: { type: "webassembly" },              });           

添加該功能的主要目的是處于安全性考慮,防止響應伺服器意外提供不同的 MIME 類型,進而導緻代碼意外執行的情況。

TypeScript 5.3 初探,有你想要的功能嗎?

支援 throw 異常

throw 表達式是 JavaScript 裡的一種文法,這是一種在不使用語句的情況下抛出異常的一種方式,可以寫成:

const id = searchParams.id || throw new Error("id is required");           

這種方式在 JavaScript 中并不可用,在 TypeScript 中會抛出一個錯誤:

const id = searchParams.id || throw new Error("id is required");           
Expression expected.

然而,throw 表達式在 TypeScript 5.3 中不太可能實作。該提案仍處于第2階段,離添加到 TypeScript 所需的第3階段還有一段距離。

但 TypeScript 疊代計劃特别增加了對這個提案的“支援”。這意味着他們正在積極地開展工作,是以它有可能在未來的 JavaScript/TypeScript 版本中實作。

TypeScript 5.3 初探,有你想要的功能嗎?

隔離聲明(Isolated Declarations)

在一個包含許多軟體包的單一代碼庫中,你可能會遇到互相依賴的情況。這種情況下,你可能會得到一個非常深層次、類似于“家族樹”的結構,其中軟體包 A 依賴于軟體包 B,而軟體包 B 又依賴于軟體包 C,以此類推。

在這種情況下,TypeScript 的檢查可能會變得非常緩慢。首先必須檢查 D 包,然後是 C 包、B包,最後才是A包。

造成這種情況的原因是 TypeScript 本身需要列印每個包的聲明檔案(.d.ts檔案),這也意味着對它們進行類型檢查,該過程很慢。

一種提速方法是讓更快的工具,如 esbuild 或 swc 為每個包建立聲明檔案。但目前這是不可能的。TypeScript 對于需要添加多少注釋到代碼中并沒有嚴格要求。第三方工具無法根據推斷生成聲明檔案。

引入隔離聲明 - 這是 TypeScript 的一種新、更嚴格的模式,可以解決這個問題。

可以在 tsconfig.json 添加一個選項:

{              "compilerOptions": {              "isolatedDeclarations": true              }              }           

一旦啟用,它便會要求開發者人員嚴格添加注釋,具體如何要求仍在讨論中,并可能随時間的變化而改變。作為一個 Demo,導出函數的傳回類型注釋很可能是強制性的,以避免 TypeScript 需要推斷它們。

開發者隻需要在共享包上啟用 isolatedDeclarations - 你不需要在應用程式代碼上啟用它。限制共享包的做法可能是可取的,因為通常情況下,開發者會希望對共享包添加更多的注釋。

泛型函數縮小範圍

在處理通用函數時,我給出的一個建議是“不要害怕使用 as”。目前的 TypeScript 在通用函數内部的縮小類型方面表現并不理想。

例如:

TypeScript 5.3 初探,有你想要的功能嗎?

上述代碼正在嘗試根據 key 從對象中傳回一個值。如果傳入'foo',将傳回一個字元串。如果傳入'bar',則是傳回一個數字。

代碼看起來沒問題,可殊不知 TypeScript 卻報錯了。

原因則是 TypeScript 沒有将 Example[T] 縮小為正确的 key,一旦對 Example[T] 進行縮小操作,就會導緻它被類型化為 never,是以報錯。

目前唯一能讓該段程式正常運作的方法是将其輸入為“never”。

function exampleFunc<T extends keyof Example>(              key: T              ): Example[T] {              if (key === "foo") {              return "abc" as never;              } else {              return 123 as never;              }              }           

感覺真的很糟。

TypeScript 5.3 可能會在這裡進行一些更改。有個 long-open issue 提到了做此更改的動機。

此項更對我來說是非常高興的事情。這裡的泛型錯誤推斷于開發者而言,并不容易,如果 TypeScript 在此類錯誤下變的更聰明一些,那開發者用起泛型會更加容易。

TypeScript 5.3 初探,有你想要的功能嗎?

字元串自動補全

TypeScript 裡面有個著名的字元串補全技巧,就是使用 string&{}來實作自動寬松補全:

type IconSize =              | "small"              | "medium"              | "large"              | (string & {});           

該注釋看起來很奇怪,但它存在的原因是為了讓你在傳遞任何值給 IconSize 的同時,還能獲得其他三個值的自動補全。

const icons: IconSize[] = [              "small",              "medium",              "large",              "extra-large",              "anything-goes",              ];           

TypeScript 5.3 可能會推出一個新功能,使得這個 hack 變得不再必要。開發者将能夠使用字元串作為類型,并獲得相同的自動補全功能。

type IconSize =              | "small"              | "medium"              | "large"              | string;           

這将非常受歡迎 - 尤其是因為 Webstorm 使用者已經擁有了多年。

TypeScript 5.3 初探,有你想要的功能嗎?

fetch in @types/node

在 2022 年 2 月 1 日,Node.js 團隊合并了一個拉取請求,将 Fetch API 添加到 Node.js 中。這意味着 Node.js 将擁有一個像浏覽器一樣的 fetch 函數。但該功能尚未被添加到 @types/node 中,目前該問題在 DefinitelyTyped 闆塊下引發了激烈讨論。