// 之前的写法 async function showQuickPick( prompt: string, selectionKind: SelectionKind, items: readonly string[], ): Promise<string | string[]> { // 实现代码 } // 堆代码 duidaima.com // 使用时需要手动检查类型 let result = await showQuickPick( "选择水果", SelectionKind.Multiple, ["苹果", "香蕉", "橙子"] ); // 错误:无法确定 result 是 string 还是 string[] console.log(`已选择: ${result.join(", ")}`);TypeScript 5.8 的解决方案
type QuickPickReturn<S extends SelectionKind> = S extends SelectionKind.Multiple ? string[] : string; asyncfunction showQuickPick<S extends SelectionKind>( prompt: string, selectionKind: S, items: readonly string[], ): Promise<QuickPickReturn<S>> { // 实现代码 } // TypeScript 自动推断正确的返回类型 let multipleResult = await showQuickPick( "选择水果", SelectionKind.Multiple, ["苹果", "香蕉", "橙子"] ); // 类型为 string[] let singleResult = await showQuickPick( "选择一个水果", SelectionKind.Single, ["苹果", "香蕉", "橙子"] ); // 类型为 string // 现在可以安全地使用 join 方法 console.log(`已选择: ${multipleResult.join(", ")}`);这种改进不仅让代码更加简洁,还在编译时就能捕获潜在的类型错误,大大提高了代码的可靠性。
2.CommonJS 文件不能 require() ESM 文件 ❌
这给库作者带来了巨大挑战,他们要么放弃对 CommonJS 用户的兼容性,要么选择"双重发布"(为 ESM 和 CommonJS 提供单独的入口点),或者干脆停留在 CommonJS 上。但,这一次模块互操作性有重大突破!
// 在 --module nodenext 下,以下代码不再报错 const esmModule = require('./myEsmModule.mjs');这对库作者来说是个重大利好,他们现在可以在不进行复杂的双重发布的情况下提供 ESM 支持。
.对于库作者和旧版 Node.js 用户,建议继续使用 --module node16 或升级到 --module node18
.导入别名
// 启用 --erasableSyntaxOnly 后 class Point { constructor(public x: number, public y: number) { } // ~~~~~~~~~~~~~~~~ // 错误! 当启用 'erasableSyntaxOnly' 时,不允许使用这种语法。 }通过启用这个标志,你可以在编译时就发现潜在的兼容性问题,而不是等到运行时才遇到错误。
export let propName = "answer"; exportclass MyClass { [propName] = 42; } // 生成的声明文件: exportdeclarelet propName: string; exportdeclareclass MyClass { [x: string]: number; // 泛化为索引签名 } TypeScript 5.8 的改进 export let propName = "answer"; exportclass MyClass { [propName] = 42; } // 生成的声明文件: exportdeclarelet propName: string; exportdeclareclass MyClass { [propName]: number; // 保留了原始的计算属性名 }这一改进使得声明文件更加准确,提高了类型检查的精确度,特别是在使用复杂对象结构时。
// 不推荐 import data from "./data.json" assert { type: "json" }; // 推荐 import data from "./data.json" with { type: "json" };DOM 类型更新 lib.d.ts 文件进行了更新,可能会影响依赖 DOM 类型的代码库。
npm install -D typescript@latest如果你使用的是 Visual Studio Code,也可以更新 TypeScript 工具来体验这些新特性。
// TypeScript 5.8 之前 asyncfunction fetchData(endpoint: string, options?: RequestOptions): Promise<any> { // 实现代码 } // 使用时需要手动类型断言 const userData = await fetchData('/users') as User[]; const productData = await fetchData('/products') as Product[]; // TypeScript 5.8 asyncfunction fetchData<T extends Endpoint>( endpoint: T, options?: RequestOptions ): Promise<EndpointResponse<T>> { // 实现代码 } // 自动推断正确的返回类型 const userData = await fetchData('/users'); // 类型为 User[] const productData = await fetchData('/products'); // 类型为 Product[]这种改进不仅减少了代码量,还提高了类型安全性,避免了手动类型断言可能带来的错误。
// 之前需要维护两套入口点 // package.json { "main": "dist/cjs/index.js", "module": "dist/esm/index.js", "exports": { "import": "./dist/esm/index.js", "require": "./dist/cjs/index.js" } } // 现在可以简化为 { "type": "module", "main": "dist/index.js", "exports": "./dist/index.js" }这大大减少了维护成本,同时提高了代码的一致性。
npm install typescript@next