你是否理解 tsconfig 中的 target 和 lib ?

328 阅读4分钟

target

target 配置项用于指定 TypeScript 编译器将代码编译后所生成的 JavaScript 版本。它决定了输出的 JavaScript 代码所遵循的语法标准,比如 ES3、ES5、ES6 等。

target 配置会决定哪些 JavaScript 特性被降级转换,哪些特性会被保留。

例如,如果 target 设置为 ES5 或更低版本,箭头函数 () => this 将会被转换为等效的函数表达式。

对于像 Node 这样的开发平台,依据平台类型及其版本的不同,target(目标)设置存在相应的基准。你可以在 tsconfig/bases 处找到一组由社区整理的 TypeScript 配置(TSConfigs),那里有针对常见平台及其版本的配置。

当你不知道相关的开发平台,比如 BunDenoNode 等的 tsconfig 如何配置时,可以参考 tsconfig/bases 里的。

lib

lib 配置用于指定 TypeScript 编译器在编译过程中包含哪些内置库的类型声明。这些库声明为编译器提供了类型信息,帮助编译器理解和检查代码中对各种 JavaScript 对象、函数和特性的使用是否符合类型规范。

比如,当 lib 设置为 es6 时,在 TypeScript 代码中可以自动识别 MapSetes6 中新增的语言特性。

在实际的开发中,有以下几个场景需要修改 lib 配置:

  • 你的应用程序不运行在浏览器中,你不需要 dom 相关的类型定义

  • 运行时平台通过 polyfills 提供部分 API 但不支持完整语法。这时可通过调整 lib 配置,只纳入和已支持 API 对应的类型定义库,避开依赖那些还不支持的语法相关的库,让 TypeScript 的类型检查契合实际可用情况

  • 有部分但非全部高版本 ECMAScript 实现或 polyfills 的情况。可在 lib 配置里选择包含已实现功能对应的类型定义库,排除依赖那些未实现功能的库,避免因假设所有功能都存在而产生类型检查错误,使类型检查贴合实际运行环境的功能支持状况

比如,有个 JavaScript 的运行时平台,通过 polyfills 实现了部分 Promise 的 API ,但是还不支持 Promise.prototype.finally() , 这时可在 lib 中指定 ES2015.Promise 来反映这个情况,避免开发人员误用 Promise.prototype.finally()

41.png

TypeScript 代码中使用了 Promise.prototype.finally() 就会有错误提示:

42.png

在 tsconfig 的 lib 配置中,可基于程序运行环境(是否是浏览器环境)、运行时平台对 JavaScript 语法及 API 的支持情况(部分支持、通过 polyfills 支持等)来灵活调整 lib 配置,以保证 TypeScript 类型检查与实际的运行环境及功能支持相符,避免不必要的类型检查错误和开销。

target 与 lib 配置的协同作用

lib 配置与 target 配置密切相关。更改 target 的配置也会更改 lib 的默认值。

例如,当 target 设置为 es5 时,编译器会自动包含 dom (用于 DOM 操作相关类型) 、es5 (用于 ES5 语法相关类型)等库声明。这些默认的库声明为在该目标版本下进行常见的 JavaScript 开发提供了基本的类型支持。

即使编译器会自动根据 target 添加一些库声明,开发者也可以根据项目需求手动添加额外的库声明。例如,当 target 设置为es5,但你想在项目中使用 es6 中新增的 MapSet 数据结构,就可以手动在 lib 配置中添加 es2015.collection。例如下面的 lib 配置:

{
  "compilerOptions": {
    "target": "es5",
    "lib": ["dom", "es5", "es2015.collection"]
  }
}

注意一旦指定了 lib ,TypeScript 便不会自动根据 target 自动包含默认的类型声明。

这样,编译器就能够理解和检查代码中关于 MapSet 的使用是否正确,提供更好的类型安全性。

因此,我们可以根据需要混合搭配 targetlib 的配置。

关于 target 为 esnext

target 设置为 esnext 时,指生成的 JavaScript 代码可以为当前使用的 TypeScript 支持的最高的 ECMAScript 语言规范的最高版本。

由于 TypeScript 会不断更新,新的 TypeScript 版本对 esnext 所涵盖的 ECMAScript 特性范围可能会发生变化,导致在升级 TypeScript 版本时,esnext 允许使用的特性和编译后的结果可能会和之前有所不同。所以,使用该设置要谨慎。

{
  "compilerOptions": {
    "target": "esnext"
  }
}

总结

target 配置项用于指定 TypeScript 编译器将代码编译后所生成的 JavaScript 版本。lib 配置用于指定 TypeScript 编译器在编译过程中包含哪些内置库的类型声明

lib 配置与 target 配置密切相关。更改 target 的配置也会更改 lib 的默认值。我们可以根据需要混合搭配 targetlib 的配置。

tsconfig 中的配置项并不是孤立的,而是会互相关联。他们互相制约,互相配合,构成了完整的 ts 项目配置。