Redon

一心的小屋

TSConfig备忘录

发布于 # TypeScript

原文来自:The TSConfig Cheat Sheet (Matt Pocock),本人翻译备份用。

tsconfig.json 文件让很多人望而生畏,因为它是一个庞大的文件,包含着大量的配置选项。

但实际上,只需要关注其中较少的几个配置选项就行了。让我们来理清这些选项,并做成简易参考。

快速开始

基本代码示例

{
  "compilerOptions": {
    /* 基础选项: */
    "esModuleInterop": true,
    "skipLibCheck": true,
    "target": "es2022",
    "allowJs": true,
    "resolveJsonModule": true,
    "moduleDetection": "force",
    "isolatedModules": true,
    "verbatimModuleSyntax": true,
    /* 严格模式 */
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    /* 如果使用 TypeScript 转码: */
    "module": "NodeNext",
    "outDir": "dist",
    "sourceMap": true,
    /* 如果要构建一个库: */
    "declaration": true,
    /* 如果要在单一仓库中构建一个库: */
    "composite": true,
    "declarationMap": true,
    /* 如果不使用 TypeScript 进行转码: */
    "module": "preserve",
    "noEmit": true,
    /* 如果代码运行在 DOM 中: */
    "lib": ["es2022", "dom", "dom.iterable"],
    /* 如果代码不运行在 DOM 中: */
    "lib": ["es2022"]
  }
}

完整说明

基本选项

以下是我推荐所有项目都使用的基础选项:

{
  "compilerOptions": {
    "esModuleInterop": true,
    "skipLibCheck": true,
    "target": "es2022",
    "allowJs": true,
    "resolveJsonModule": true,
    "moduleDetection": "force",
    "isolatedModules": true,
    "verbatimModuleSyntax": true
  }
}
  • esModuleInterop: 有助于弥合 CommonJSES Modules 之间的某些差距。

  • skipLibCheck: 跳过对 .d.ts 文件的类型检查。这对于性能很重要,否则所有 node_modules 都将被检查。

  • target: 你要编译的 JavaScript 版本。 我推荐使用 es2022 而非 esnext 以获得更好的稳定性。

  • allowJsresolveJsonModule: 允许你导入 .js.json 文件。始终很有用。

  • moduleDetection: 此选项强制 TypeScript 将所有文件视为模块。 这有助于避免“无法重新声明块级作用域变量”错误。

  • isolatedModules: 此选项阻止了一些在将模块视为独立文件时不安全的 TS 功能。

  • verbatimModuleSyntax: 此选项强制你使用 import typeexport type,从而带来更可预测的行为和减少不必要的导入。 结合module: NodeNext,它还强制你使用正确的 ESMCJS 导入语法。

严格模式

以下是我推荐所有项目使用的严格模式选项:

{
  "compilerOptions": {
    "strict": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true
  }
}
  • strict: 启用所有严格的类型检查选项。必要。

  • noUncheckedIndexedAccess: 防止你在不首先检查数组或对象是否定义的情况下进行访问。 这是一种防止运行时错误的好方法,并且应该真正包含在 strict 中。

  • noImplicitOverride: 使 override 关键字在类中真正有用。

许多人推荐 tsconfig/bases 中的严格模式选项,这是一个很棒的存储库,它列举了 TSConfig 选项。 但这些选项包含了许多我认为过于“繁琐”的规则,例如 noImplicitReturnsnoUnusedLocalsnoUnusedParametersnoFallthroughCasesInSwitch。 我建议仅在你想要它们时才将这些规则添加到你的 tsconfig.json 中。

使用 TypeScript 进行转码

如果你正在使用 tsc 转码你的代码(创建 JavaScript 文件),则需要以下选项:

{
  "compilerOptions": {
    "module": "NodeNext",
    "outDir": "dist"
  }
}
  • module: 告诉 TypeScript 要使用什么模块语法。 NodeNext 是适用于 Node 的最佳选项。 moduleResolution: NodeNext 可以从这个选项推断出来。

  • outDir: 告诉 TypeScript 将编译后的 JavaScript 文件放在哪里。 dist 是我的首选约定,但这由你决定。

构建库

如果你要构建一个库,则需要 declaration: true

{
  "compilerOptions": {
    "declaration": true
  }
}
  • declaration: 在 tsconfig.json 文件中告诉 TypeScript 声明 .d.ts 文件。

单仓库中的库构建

如果您要为单仓库中的库构建,那么您还需要以下选项:

{
  "compilerOptions": {
    "declaration": true,
    "composite": true,
    "sourceMap": true,
    "declarationMap": true
  }
}
  • composite: 告诉 TypeScript 声明 .tsbuildinfo 文件。这会告诉 TypeScript 你的项目是单仓库,并且还有助于缓存构建以更快地运行。

  • sourceMapdeclarationMap: 告诉 TypeScript 声明映射。当库的使用者进行调试时,需要这些选项以便他们可以使用跳转到定义功能来跳转到原始源代码。

不使用 TypeScript 进行转译

如果您不使用 tsc 转译您的代码,即更像使用 TypeScript 作为 linter,那么您将需要以下选项:

{
  "compilerOptions": {
    "module": "preserve",
    "noEmit": true
  }
}
  • module: preserve 是最佳选项,因为它最接近捆绑器处理模块的方式。由此选项暗示了 moduleResolution: Bundler

  • noEmit: 告诉 TypeScript 不发出任何文件。当您使用捆绑器时,这很重要,这样就不会发出无用的 .js 文件。

DOM 中运行

如果你的代码在 DOM 中运行,则需要以下选项:

{
  "compilerOptions": {
    "lib": ["es2022", "dom", "dom.iterable"]
  }
}
  • lib: 告诉 TypeScript 要包含哪些内置类型。es2022 是稳定性的最佳选择。domdom.iterable 为您提供 windowdocument 等的类型。

不在 DOM 中运行

如果你的代码不在 DOM 中运行,则您需要 lib: ["es2022"]

{
  "compilerOptions": {
    "lib": ["es2022"]
  }
}

这与上面相同,但没有 domdom.iterable 类型。