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

TypeScript 5.4 正式發布,一起來看看該版本帶來了那些更新

開發 前端
TypeScript 5.4 將是這些已廢棄選項和行為按預期運作的最后一個版本。在預計于 2024 年 6 月發布的 TypeScript 5.5 中,這些選項和行為將變成嚴格的錯誤,使用它們的代碼將需要進行遷移以避免編譯錯誤。

3 月 6 日,TypeScript 發布了 v5.4 版本,該版本帶來了以下更新:

  • 類型縮小會在閉包中保留
  • 引入新的實用程序類型 NoInfer<T>
  • 新增Object.groupBy 和 Map.groupBy
  • 新的模塊解析選項
  • 新的模塊導入檢查機制
  • TypeScript 5.5 即將棄用的功能

類型縮小會在閉包中保留

TypeScript 通過類型縮小來優化代碼,但在閉包中并不總是保留這些縮小后的類型。從TypeScript 5.4開始,當在非提升函數中使用參數或let變量時,類型檢查器會查找最后的賦值點,從而智能地進行類型縮小。然而,如果變量在嵌套函數中被重新分配,即使這種分配不影響其類型,也會使閉包中的類型細化無效。

// TypeScript的類型縮小在閉包中通常不保留  
function exampleFunction(input: string | number) {  
    if (typeof input === "string") {  
        input = parseInt(input); // 假設想要將字符串轉為數字  
    }  
  
    return () => {  
        // 在這里,TypeScript不知道input是string還是number  
        // 因為在閉包創建后,input可能已經被修改  
        console.log(input.toString()); // 錯誤!'input'可能是number,沒有toString方法  
    };  
}

TypeScript 5.4后,當在閉包外部對變量進行最后一次賦值時,類型縮小會在閉包中保留:

function improvedFunction(input: string | number) {  
    let value;  
    if (typeof input === "string") {  
        value = parseInt(input);  
    } else {  
        value = input;  
    }  
  
    return () => {  
        // 在這里,TypeScript知道value是number,因為這是在閉包創建后的最后一次賦值  
        console.log(value.toString()); // 正確!因為現在我們知道value是number  
    };  
}

引入新的實用程序類型 NoInfer

TypeScript的泛型函數能夠根據傳入的參數自動推斷類型。但在某些情況下,這種自動推斷可能不符合預期,導致不合法的函數調用被接受,而合法的調用卻被拒絕。為了處理這種情況,開發者通常需要添加額外的類型參數來約束函數的行為,確保類型安全。但這種做法可能會使代碼看起來更加復雜,特別是當這些額外的類型參數在函數簽名中只使用一次時。

TypeScript 5.4 引入了 NoInfer<T> 實用類型,允許開發者明確告訴編譯器哪些類型不應該被自動推斷。這避免了不合法的函數調用被接受,增強了代碼的類型安全性。

考慮以下函數,它接受一個用戶ID列表和一個可選的默認用戶ID。

function selectUser<U extends string>(userIds: U[], defaultUserId?: U) {  
  // ...  
}  
  
const userIds = ["123", "456", "789"];  
selectUser(userIds, "000"); // 錯誤地被接受,因為"000"不在userIds中

在這個例子中,即使"000"不在userIds數組中,selectUser函數的調用也會被接受,因為TypeScript自動推斷默認用戶ID可以是任何字符串。

TypeScript 5.4 中:

function selectUser<U extends string>(userIds: U[], defaultUserId?: NoInfer<U>) {  
  // ...  
}  
  
const userIds = ["123", "456", "789"];  
selectUser(userIds, "000"); // 正確的錯誤,因為"000"不在userIds中

通過使用 NoInfer<T> 告訴 TypeScript 不要推斷默認用戶ID的類型,從而確保只有當默認用戶ID在userIds數組中時才接受調用。這增強了代碼的類型安全性,避免了潛在的錯誤。

新增 Object.groupBy 和 Map.groupBy

TypeScript 5.4 引入了兩個新方法:Object.groupBy 和 Map.groupBy,它們用于根據特定條件將數組元素分組。

  • Object.groupBy 返回一個對象,其中每個鍵代表一個分組,對應的值是該分組的元素數組。
  • Map.groupBy 返回一個`` Map 對象,實現了相同的功能,但允許使用任何類型的鍵。

使用 Object.groupBy 和 Map.groupBy 可以方便地根據自定義邏輯對數組進行分組,無需手動創建和填充對象或 Map。然而,在使用 Object.groupBy 時,由于對象的屬性名必須是有效的標識符,因此可能無法覆蓋所有情況。此外,這些方法目前僅在 esnext 目標或特定庫設置下可用。

假設有一個學生數組,每個學生都有姓名和成績。我們想要根據成績將學生分為“優秀”和“及格”兩組。

const students: { name: string, score: number }[] = [  
  { name: "Alice", score: 90 },  
  { name: "Bob", score: 75 },  
  { name: "Charlie", score: 85 },  
  // ...其他學生  
];  
  
const groupedStudents: { excellent: any[], passing: any[] } = {  
  excellent: [],  
  passing: []  
};  
  
for (const student of students) {  
  if (student.score >= 80) {  
    groupedStudents.excellent.push(student);  
  } else {  
    groupedStudents.passing.push(student);  
  }  
}

使用 Array.prototype.groupBy 方法,可以更簡潔地實現相同的功能。

const students: { name: string, score: number }[] = [  
  { name: "Alice", score: 90 },  
  { name: "Bob", score: 75 },  
  { name: "Charlie", score: 85 },  
  // ...其他學生  
];  
  
const groupedStudents = students.groupBy(student => {  
  return student.score >= 80 ? "excellent" : "passing";  
});  
  
// 使用時可以直接訪問分組  
console.log(groupedStudents.get("excellent")); // 輸出優秀學生數組  
console.log(groupedStudents.get("passing")); // 輸出及格學生數組

在這個例子中,groupBy 方法根據每個學生的成績將學生數組分為“優秀”和“及格”兩組,并返回一個 Map 對象,其中鍵是分組名稱,值是對應的學生數組。這種方法更加簡潔且易于理解。

新的模塊解析選項

TypeScript 5.4 引入了一個新的模塊解析選項 bundler,它模擬了現代構建工具(如Webpack、Vite 等)確定導入路徑的方式。當與 --module esnext 配合使用時,它允許開發者使用標準的 ECMAScript 導入語法,但禁止了 import ... = require(...) 這種混合語法。

同時,TypeScript 5.4 還增加了一個名為 preserve 的模塊選項,該選項允許開發者在 TypeScript 中使用 require(),并更準確地模擬了構建工具和其他運行時環境的模塊查找行為。當設置 module 為 preserve 時,構建工具會隱式地成為默認的模塊解析策略,同時啟用 esModuleInterop 和 resolveJsonModule。

假設有一個使用 TypeScript 編寫的項目,并且想從一個名為 my-lib 的庫中導入兩個模塊 moduleA 和 moduleB。這個庫提供了 ES 模塊和 CommonJS 模塊兩種格式。在 TypeScript 配置中,你可能這樣設置:

// tsconfig.json  
{  
  "compilerOptions": {  
    "module": "commonjs",  
    "moduleResolution": "node"  
  }  
}

然后代碼中這樣導入:

import * as moduleA from 'my-lib/moduleA';  
import * as moduleB = require('my-lib/moduleB');

在這種情況下,TypeScript 可能會為兩個導入生成相同的路徑,因為它們都使用了 Node.js 的模塊解析策略。

在 TypeScript 5.4 中,如果想更精確地控制導入的路徑,特別是當庫提供了基于導入語法的不同實現時,可以使用 preserve 模塊選項和構建工具模塊解析策略:

// tsconfig.json  
{  
  "compilerOptions": {  
    "module": "preserve",  
    // 隱式設置:  
    // "moduleResolution": "bundler",  
    // "esModuleInterop": true,  
    // "resolveJsonModule": true  
  }  
}

然后,可以這樣編寫代碼:

import * as moduleA from 'my-lib/moduleA'; // 使用 ES 模塊導入  
const moduleB = require('my-lib/moduleB'); // 使用 CommonJS 模塊導入

現在,TypeScript 會根據 my-lib 的 package.json 文件中的 exports 字段來決定使用哪個文件路徑。如果庫為 ES 模塊和 CommonJS 模塊提供了不同的文件,TypeScript 將根據導入的語法(import 或 require)選擇正確的文件。

這意味著開發者可以更精細地控制模塊導入的行為,確保與庫的意圖一致,尤其是在處理那些提供條件導出的庫時。

新的模塊導入檢查機制

TypeScript 5.4 引入了新的模塊導入檢查機制,確保導入的屬性與全局定義的 ImportAttributes 接口相匹配。這種檢查提高了代碼的準確性,因為任何不符合該接口的導入屬性都會導致編譯錯誤。

在早期的 TypeScript 版本中,開發者可以自由地為 import 語句指定任何導入屬性,而不會有嚴格的類型檢查。這可能導致運行時錯誤,因為導入的屬性可能與實際的模塊不匹配。

// 假設存在一個全局的模塊定義,但沒有明確的導入屬性類型  
import * as myModule from 'my-module' with { custom: 'value' };

在上述代碼中,custom 屬性是自由定義的,沒有與任何全局接口或類型進行匹配,這增加了出錯的風險。

在 TypeScript 5.4 及以后的版本中,開發者必須確保導入屬性與全局定義的 ImportAttributes 接口相符。這確保了類型安全,并減少了潛在的運行時錯誤。

// 全局定義的導入屬性接口  
interface ImportAttributes {  
    validProperty: string;  
}  
  
// 在模塊中導入時,必須使用符合 ImportAttributes 接口的屬性  
import * as myModule from 'my-module' with { validProperty: 'someValue' };  
  
// 下面的導入將引發錯誤,因為屬性名稱不匹配  
import * as myModule from 'my-module' with { invalidProperty: 'someValue' };  
// 錯誤:屬性 'invalidProperty' 不存在于類型 'ImportAttributes' 中

在這個新版本中,如果開發者嘗試使用不符合 ImportAttributes 接口的導入屬性,TypeScript 編譯器將拋出錯誤,從而避免了潛在的錯誤。

TypeScript 5.5 即將棄用的功能

TypeScript 5.0 已經廢棄了以下選項和行為:

  • charset
  • target: ES3
  • importsNotUsedAsValues
  • noImplicitUseStrict
  • noStrictGenericChecks
  • keyofStringsOnly
  • suppressExcessPropertyErrors
  • suppressImplicitAnyIndexErrors
  • out
  • preserveValueImports
  • 在項目引用中的prepend
  • 隱式OS特定的newLine

為了在 TypeScript 5.0 及更高版本中繼續使用這些已廢棄的選項和行為,開發人員必須指定一個新的選項 ignoreDeprecations,并將其值設置為 "5.0"。

注意,TypeScript 5.4 將是這些已廢棄選項和行為按預期運作的最后一個版本。在預計于 2024 年 6 月發布的 TypeScript 5.5 中,這些選項和行為將變成嚴格的錯誤,使用它們的代碼將需要進行遷移以避免編譯錯誤。因此,建議開發人員盡早遷移其代碼庫,以避免未來兼容性問題。

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

2024-12-06 08:00:51

2024-05-24 08:35:00

Angular 18版本更新

2024-03-21 08:21:34

Java 22Java 語言開發工具包

2023-10-20 10:11:00

Nuxt 3.8前端

2022-03-18 08:16:51

微軟Windows 11

2022-06-24 06:32:46

iOS 16Beta 2

2021-09-09 08:47:52

Dependency 安全漏洞工具

2021-07-15 05:26:22

Windows 10操作系統微軟

2021-05-14 05:20:45

Windows10操作系統微軟

2021-10-11 08:21:23

@Valuespringspring框架

2024-04-23 10:29:44

SassCSS前端

2022-02-07 13:34:05

冬奧會黑科技機器人

2010-05-10 17:21:26

Unix操作系統

2024-04-09 10:10:23

GridCSS網格

2022-08-29 15:30:46

TypeScript代碼

2021-06-11 05:19:19

Windows10操作系統微軟

2021-11-17 10:45:58

Chrome 95新特性前端

2023-10-18 10:10:29

Node.js 21前端

2015-11-10 09:57:18

APP流量

2025-01-07 08:20:49

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 精品福利av导航 | 国产精品欧美日韩 | 成人国产免费视频 | 一区二区三区欧美 | 欧美 日韩 亚洲91麻豆精品 | 一区二区在线观看免费视频 | 欧美一区二区三区四区五区无卡码 | 精品国产一区二区三区av片 | 大学生a级毛片免费视频 | 精品三区 | 亚洲精品粉嫩美女一区 | 久久久久国产一区二区三区 | 91亚洲精选| 免费在线精品视频 | 亚洲精品一区二区三区中文字幕 | 97人人澡人人爽91综合色 | 日韩欧美在线免费观看视频 | 成人国产精品色哟哟 | 精品欧美一区二区三区免费观看 | 精品九九 | 国产精品久久久久久52avav | 国产精品美女久久久久aⅴ国产馆 | 中文字幕一区二区视频 | 色综合色综合 | 欧美综合国产精品久久丁香 | 国产精品久久久久久久久久久久久久 | 亚洲图片一区二区三区 | 色又黄又爽网站www久久 | 天天躁日日躁狠狠躁2018小说 | 天堂在线网 | 欧美一级欧美一级在线播放 | 久久久久国产精品一区二区 | 欧美久久久久久 | 午夜影院在线免费观看视频 | 午夜伊人 | 久久久久久国产精品免费免费狐狸 | 亚洲精品免费视频 | 91成人精品 | 国产www.| 国产高清美女一级a毛片久久w | 欧美一区二 |