成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

TypeScript 5.3 來了,一大波新特性

開發 前端
TypeScript 5.3 支持導入屬性提案的最新更新。導入屬性的一個用例是向運行時提供有關模塊的預期格式的信息。

根據 TypeScript 路線圖,TypeScript 5.3 計劃于 11 月 14 日發布。

圖片

下面是該版本帶來的新特性:

  • 導入屬性
  • 導入類型中穩定支持 resolution-mode
  • 所有模塊模式均支持 resolution-mode
  • switch (true) 縮小范圍
  • 對布爾值進行比較的縮小范圍
  • 通過 Symbol.hasInstance 進行 instanceof 類型縮小
  • 實例字段上的 super 屬性訪問檢查
  • 嵌入提示支持跳轉到類型的定義
  • 通過跳過 JSDoc 解析進行優化
  • 通過比較非標準交集進行優化
  • 整合 tsserverlibrary.js 和 typescript.js

導入屬性

TypeScript 5.3 支持導入屬性提案的最新更新。導入屬性的一個用例是向運行時提供有關模塊的預期格式的信息。

// 希望將這個文件解釋為 JSON 數據,而不是一個帶有 .json 擴展名的可執行/惡意的 JavaScript 文件。
import obj from "./something.json" with { type: "json" };

這些屬性的內容不會被 TypeScript 檢查,因為它們是特定于宿主環境的,并且會被直接保留,以便瀏覽器和運行時環境可以處理它們(并可能會出現錯誤)。

// TypeScript 對此沒有問題,但是瀏覽器可能不支持。
import * as foo from "./foo.js" with { type: "fluffy bunny" };

動態 import() 調用還可以通過第二個參數使用導入屬性。

const obj = await import("./something.json", {
    with: { type: "json" }
});

第二個參數的預期類型由名為 ImportCallOptions 的類型定義,該類型默認情況下只需要一個名為 with 的屬性。

注意,導入屬性是早期提案“導入斷言”的演進版本,該提案已在 TypeScript 4.5 中實現。最明顯的區別是使用 with 關鍵字而不是 assert 關鍵字。但不太明顯的區別在于,現在運行時可以自由地使用屬性來引導導入路徑的解析和解釋,而導入斷言只能在加載模塊后斷言某些特征。

隨著時間的推移,TypeScript 將逐漸棄用舊的導入斷言語法,并傾向于使用導入屬性的提案語法。現有使用 assert 的代碼應該遷移到使用 with 關鍵字。需要使用導入屬性的新代碼應該使用 with。

resolution-mode

導入類型中穩定支持 resolution-mode

在 TypeScript 4.7 中,TypeScript 增加了對 /// <reference types="..." /> 中的 resolution-mode 屬性的支持,以控制特定規范符號是應該通過 import 還是 require 語義進行解析。

/// <reference types="pkg" resolution-mode="require" />

// 或

/// <reference types="pkg" resolution-mode="import" />

考慮到導入屬性可以引導解析,并且已經看到了合理的使用案例,TypeScript 5.3 現在支持 import type 的 resolution-mode 屬性。

// 以使用 `require()` 進行導入的方式解析 `pkg`
import type { TypeFromRequire } from "pkg" with {
  "resolution-mode": "require"
};

// 以使用 `import` 進行導入的方式解析 `pkg`
import type { TypeFromImport } from "pkg" with {
  "resolution-mode": "import"
};

export interface MergedType extends TypeFromRequire, TypeFromImport {}

這些導入屬性也可以用于 import() 類型。

export type TypeFromRequire =
  import("pkg", { with: { "resolution-mode": "require" } }).TypeFromRequire;

export type TypeFromImport =
  import("pkg", { with: { "resolution-mode": "import" } }).TypeFromImport;

export interface MergedType extends TypeFromRequire, TypeFromImport {}

所有模塊模式均支持 resolution-mode

以前,只有在 moduleResolution 選項為 node16 和 nodenext 時才允許使用 resolution-mode。為了更容易地專門查找用于類型的模塊,現在 resolution-mode 在所有其他 moduleResolution 選項中都能正常工作,比如 bundler、node10,在 classic 模式下則不會報錯。

類型縮小優化

switch (true)

現在 TypeScript 5.3 能夠根據 switch 中每個 case 子句的條件進行類型細化。

function f(x: unknown) {
    switch (true) {
        case typeof x === "string":
            // 這里,'x' 是一個 'string'
            console.log(x.toUpperCase());

        case Array.isArray(x):
            // 這里 'x' 是一個 'string | any[]'
            console.log(x.length);

        default:
          // 這里 'x' 是 'unknown'
          // ...
    }
}

布爾值比較

有時候你可能會在條件語句中直接與 true 或 false 進行比較。通常這些比較是不必要的,但可能出于代碼風格或避免 JavaScript 真值方面的某些問題而偏好這種寫法。然而,在之前的 TypeScript 版本中,它不能正確地識別這種形式來執行類型縮小。

TypeScript 5.3 現在在縮小變量范圍時可以跟上并理解這些表達式。

interface A {
    a: string;
}

interface B {
    b: string;
}

type MyType = A | B;

function isA(x: MyType): x is A {
    return "a" in x;
}

function someFn(x: MyType) {
    if (isA(x) === true) {
        console.log(x.a); // works!
    }
}

Symbol.hasInstance

JavaScript 的一個特性是可以重寫 instanceof 運算符的行為。要實現這一點,需要在 instanceof 運算符右側的值上定義一個名為 Symbol.hasInstance 的特定方法。

class Weirdo {
    static [Symbol.hasInstance](testedValue) {
        return testedValue === undefined;
    }
}

// false
console.log(new Thing() instanceof Weirdo);

// true
console.log(undefined instanceof Weirdo);

為了更好地模擬 instanceof 運算符的行為,TypeScript 現在會檢查是否存在 [Symbol.hasInstance] 方法,并且該方法被聲明為類型斷言函數。如果存在這樣的方法,那么通過 instanceof 運算符對左側測試的值將會被相應地進行類型縮小。

interface PointLike {
    x: number;
    y: number;
}

class Point implements PointLike {
    x: number;
    y: number;

    constructor(x: number, y: number) {
        this.x = x;
        this.y = y;
    }

    distanceFromOrigin() {
        return Math.sqrt(this.x ** 2 + this.y ** 2);
    }

    static [Symbol.hasInstance](val: unknown): val is PointLike {
        return !!val && typeof val === "object" &&
            "x" in val && "y" in val &&
            typeof val.x === "number" &&
            typeof val.y === "number";
    }
}


function f(value: unknown) {
    if (value instanceof Point) {
        // 可以訪問這兩個屬性 - 正確!
        value.x;
        value.y;

        // 無法訪問這個屬性,有 'PointLike' 類型的對象,但實際上并沒有 'Point' 類型的對象。
        value.distanceFromOrigin();
    }
}

在這個例子中,Point 定義了自己的 [Symbol.hasInstance]方法。它實際上充當了一個對稱為 PointLike 的獨立類型的自定義類型保護程序。在函數 f 中,我們能夠通過 instanceof 將 value 縮小到 PointLike 類型,但無法縮小到 Point 類型。這意味著可以訪問屬性 x 和 y,但無法訪問 distanceFromOrigin 方法。

實例字段上的 super 屬性訪問檢查

在 JavaScript 中,可以通過 super 關鍵字訪問基類中的聲明。

class Base {
    someMethod() {
        console.log("Base method called!");
    }
}

class Derived extends Base {
    someMethod() {
        console.log("Derived method called!");
        super.someMethod();
    }
}

new Derived().someMethod();

// 輸出結果:
//   Derived method called!
//   Base method called!

這與編寫像 this.someMethod() 這樣的代碼是不同的,因為那樣可能會調用一個被重寫的方法,如果一個聲明根本沒有被重寫,那么通常這兩種方式是可以互換的。

class Base {
    someMethod() {
        console.log("someMethod called!");
    }
}

class Derived extends Base {
    someOtherMethod() {
        // These act identically.
        this.someMethod();
        super.someMethod();
    }
}

new Derived().someOtherMethod();

// 輸出結果:
//   someMethod called!
//   someMethod called!

問題在于這兩種方式是不能互換使用的,因為 super 只能用于在原型上聲明的成員,而不能用于實例屬性。這意味著如果你寫了 super.someMethod(),但 someMethod 被定義為一個字段,那么就會出現運行時錯誤!

class Base {
    someMethod = () => {
        console.log("someMethod called!");
    }
}

class Derived extends Base {
    someOtherMethod() {
        super.someMethod();
    }
}

new Derived().someOtherMethod();

TypeScript 5.3 現在更仔細地檢查 super 屬性訪問/方法調用,以查看它們是否對應于類字段。如果是的話,現在會得到一個類型檢查錯誤。

嵌入提示支持跳轉到類型的定義

TypeScript 的嵌入提示現在支持跳轉到類型的定義!

按住 Ctrl 鍵單擊嵌入提示可跳轉至參數類型的定義。

通過跳過 JSDoc 解析進行優化

通過 tsc 運行 TypeScript 時,編譯器現在將避免解析 JSDoc。這不僅減少了解析時間,還減少了存儲注釋的內存使用量以及垃圾收集所花費的時間。可以在 --watch 模式下看到稍快的編譯速度和更快的反饋。

通過比較非標準交集進行優化

在 TypeScript 中,并集和交集始終遵循特定的形式,其中交集不能包含并集類型。這意味著當我們在 A & (B | C) 這樣的并集上創建交集時,該交集將被標準化為 (A & B) | (A & C)。盡管如此,在某些情況下,類型系統仍會出于顯示目的而保留原始形式。

舉個例子,假設我們有 SomeType & (Type1 | Type2 | ... | Type99999NINE),我們想要確定它是否可以賦值給 SomeType,源類型是一個看起來像 (SomeType & Type1) | (SomeType & Type2) | ... |(SomeType & Type99999NINE) 的聯合類型。在檢查一個聯合類型是否可以賦值給某個目標類型時,必須檢查聯合類型的每個成員是否可以賦值給目標類型,這可能會非常慢。

在 TypeScript 5.3 中,當比較類型時,會快速檢查目標類型是否存在于源交集中的任何成員中。

整合 tsserverlibrary.js 和 typescript.js

TypeScript 本身提供了兩個庫文件:tsserverlibrary.js 和 typescript.js。在 tsserverlibrary.js 中只有特定的 API(例如 ProjectService API)。然而,這兩個是不同包,它們有許多重疊之處,在包中重復了很多代碼。更重要的是,由于自動導入或肌肉記憶,要始終一致地使用其中一個可能會很具有挑戰性。意外加載兩個模塊太容易了,代碼在不同的 API 實例上可能無法正常工作。即使它能夠正常工作,加載第二個包會增加資源使用率。

鑒于此,TypeScript 團隊決定整合兩者。 typescript.js 現在包含 tsserverlibrary.js 的內容,并且 tsserverlibrary.js 現在只是重新導出 typescript.js。整合之后,包大小減少了 20.5%。

責任編輯:姜華 來源: 前端充電寶
相關推薦

2021-12-20 09:47:20

TailwindCSS前端開發

2015-08-03 11:50:18

灌水動畫

2015-08-20 09:27:16

2015-10-15 11:15:32

阿里云云棲大會云計算

2023-07-06 16:41:55

iOS 17蘋果

2015-05-19 13:58:50

iPhone

2014-12-11 10:28:48

Ucloud

2015-04-23 20:56:22

Unity

2017-01-12 20:29:19

存儲術語DevOps

2024-06-13 09:02:30

2024-04-10 12:42:51

AI模型

2018-04-12 14:56:49

Android劉海屏技巧

2014-02-26 09:54:43

2020-10-22 20:00:27

AI機器人人工智能

2020-04-24 12:48:01

新基建物聯網IOT

2014-07-17 09:50:27

2020-02-24 09:45:06

WindowsWindows 10微軟

2015-08-03 10:24:59

Windows 10更新功能

2020-12-07 06:13:31

Windows10Update應用程序
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 蜜桃视频在线观看免费视频网站www | 国产91久久久久 | 亚洲美女网站 | 欧美视频精品 | 欧美日韩国产传媒 | 亚洲电影在线播放 | 日日操天天射 | 亚洲成人精| 九色在线视频 | 国产yw851.c免费观看网站 | 久久久免费 | 中文字幕一区二区三区四区 | 国产一级在线观看 | julia中文字幕久久一区二区 | 亚洲高清中文字幕 | 欧美视频二区 | 在线看免费 | 亚洲一二三视频 | av中文在线 | 99成人精品 | 国产亚洲精品久久久久久牛牛 | 日韩高清一区 | 国产一区二区精品在线观看 | 美女久久久久久久 | 成人在线视频网站 | 国产精品伦一区二区三级视频 | 黄色在线免费观看 | 欧美 日韩 在线播放 | 国产中文字幕在线观看 | 亚洲天堂精品久久 | 日韩精品一区二区三区四区视频 | 亚洲视频免费在线播放 | 久久久久久久久91 | 99视频免费在线 | 欧美午夜视频 | 国产毛片久久久久久久久春天 | 国产成人久久 | 日本精品久久久久久久 | 国产成人精品a视频一区www | 性一交一乱一伦视频免费观看 | 一区中文字幕 |