TypeScript tsconfig 配置

tsconfig.json 是每个 TS 项目的"控制中枢"——它决定 tsc 怎么编译、用哪些类型库、严格到什么程度。配置项有几十个,但实际常用的就十几个。这一章把必须懂的几个核心选项讲清楚,并给出新项目推荐配置。

1. tsconfig.json 的整体结构

每个 TS 项目根目录放一个 tsconfig.json。它分三大块:compilerOptions(编译选项)、include(哪些文件参与编译)、exclude(哪些文件排除):

// tsconfig.json —— 每个TS项目的"控制中枢"
// 它告诉 tsc:编译成什么 JS、用哪些类型库、严格到什么程度
{
  "compilerOptions": {
    "target": "ES2020",           // 编译成哪个版本的 JS
    "module": "ESNext",           // 输出哪种模块系统
    "moduleResolution": "bundler",// 模块解析策略
    "lib": ["ES2020", "DOM"],     // 启用哪些类型库
    "strict": true,               // 开启所有严格检查(强烈推荐)
    "outDir": "./dist",           // 编译输出目录
    "rootDir": "./src",           // 源代码根目录
    "esModuleInterop": true,      // 兼容 CommonJS 的默认导入
    "skipLibCheck": true,         // 跳过 .d.ts 的类型检查(加快速度)
    "forceConsistentCasingInFileNames": true
  },
  "include": ["src/**/*"],        // 哪些文件参与编译
  "exclude": ["node_modules", "dist"]
}

2. strict:最重要的选项

strict: true 一次性开启所有严格类型检查。这是新项目必开的选项——它能把 TS 的价值发挥到最大,挡住大量隐性 bug。它会等价于开启下面这一长串子选项:

// strict 是最重要的选项,新项目必开
// 它等价于一次性开启下面所有严格检查:
{
  "strict": true,
  // 等价于单独配置这些(都不用再写,strict 已包含):
  // "noImplicitAny": true,            // 禁止隐式 any
  // "strictNullChecks": true,         // null/undefined 必须显式处理
  // "strictFunctionTypes": true,      // 严格的函数类型检查
  // "strictBindCallApply": true,      // 严格的 bind/call/apply
  // "strictPropertyInitialization": true, // 类属性必须初始化
  // "noImplicitThis": true,           // 禁止不明确的 this
  // "alwaysStrict": true              // 输出 "use strict"
}

// 强烈推荐再加这一条(不在 strict 内,但很值得开)
{
  "noUncheckedIndexedAccess": true  // arr[0] 的类型是 T | undefined
}

其中最关键的是 strictNullChecks——它强制你显式处理 null/undefined,挡住了 JS 里最经典的"undefined is not a function"崩溃。强烈推荐再额外开 noUncheckedIndexedAccess,让数组下标访问(如 arr[0])返回 T | undefined,防止"取到 undefined 还以为是 T"的 bug。

3. target 与 lib

target 决定编译成哪个版本的 JS——版本越低,TS 会把新语法降级翻译成老语法。lib 决定能用哪些全局 API 的类型

// target:编译成哪个版本的 JS
// 选低版本:TS 会把新语法"降级翻译"成老语法(如箭头函数→普通函数)
{
  "target": "ES5",      // 兼容古董浏览器(IE)
  "target": "ES2020",   // 现代浏览器主流(推荐)
  "target": "ESNext",   // 最新(假设运行环境支持所有新特性)
}

// lib:启用哪些类型库(决定能用哪些全局 API 的类型)
{
  "lib": ["ES2020", "DOM"]
  //   ES2020 提供 Promise.allSettled、BigInt 等的类型
  //   DOM 提供 document、window、HTMLElement 等的类型
  //   (Node 项目要装 @types/node,无需在 lib 里写 "Node")
}

实战经验:target 选 ES2020(现代浏览器都支持),lib 加上 DOM(前端项目需要 DOM 类型)。Node 项目不需要 DOM,但要装 @types/node

4. module 与 moduleResolution

这两个决定模块系统模块解析策略

// module:输出哪种模块系统
{
  "module": "CommonJS",   // Node 老标准(require)
  "module": "ESNext",     // ESM(import,推荐,配合打包工具)
  "module": "NodeNext",   // Node 新版原生 ESM
}

// moduleResolution:模块解析策略(怎么根据路径找文件)
{
  "moduleResolution": "node",      // 旧版 Node 规则
  "moduleResolution": "bundler",   // 配合 Vite/Webpack 等(推荐)
  "moduleResolution": "nodenext"   // Node 新版
}

// 实战:前端项目(Vite/Next.js)推荐
{
  "module": "ESNext",
  "moduleResolution": "bundler"
}

前端项目用 Vite/Webpack 打包的,推荐 module: ESNext + moduleResolution: bundler——这是当下最顺的组合。

5. 其他常用选项

这些选项在实战中也很高频:路径别名、JSON 导入、sourceMap 等:

// 其他常用选项
{
  // 路径别名(用 @/ 代替 src/)
  "baseUrl": ".",
  "paths": {
    "@/*": ["src/*"]
  },

  // 允许 JS 文件(JS/TS 混用,迁移期有用)
  "allowJs": true,
  "checkJs": false,        // 是否检查 JS 文件的类型

  // 源码映射(调试时能看到 .ts 而不是 .js)
  "sourceMap": true,

  // 不输出编译结果(只做类型检查,编译交给 Vite/esbuild)
  "noEmit": true,

  // 解析 JSON 文件的 import
  "resolveJsonModule": true
}

注意 noEmit: true——如果你用 Vite/esbuild 来打包编译,tsc 只负责类型检查(不产出 JS),这时就该开 noEmit

6. 新项目推荐配置

给你一个开箱即用的前端(Vite/Next.js)配置,复制即用:

// 新项目推荐配置(前端 + Vite)
{
  "compilerOptions": {
    "target": "ES2020",
    "useDefineForClassFields": true,
    "module": "ESNext",
    "lib": ["ES2020", "DOM", "DOM.Iterable"],
    "skipLibCheck": true,

    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "resolveJsonModule": true,
    "isolatedModules": true,
    "noEmit": true,           // 编译交给 Vite

    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedIndexedAccess": true
  },
  "include": ["src"]
}

这份配置的特点:现代模块系统 + 最严格的类型检查 + 编译交给打包工具(tsc 只做检查)。新项目直接用,能少踩很多坑。

7. 怎么验证配置生效?

在项目根目录运行 tsc --noEmit,它会按 tsconfig.json 全量检查类型、报出所有错误,但不产出文件。这是 CI 和提交前检查的标配命令。配合 tsx 运行、Vite 开发,构成完整的 TS 工作流。

小结

tsconfig 的核心选项:strict(必开)、target(编译目标,ES2020)、lib(类型库,前端加 DOM)、module + moduleResolution(模块系统)。再加 noUncheckedIndexedAccess 让类型更严密。新项目直接抄最后一节推荐配置。至此,TypeScript 系列 15 篇全部完成——你已经掌握了从语法到工程化的全部核心,恭喜!

← 上一篇 TypeScript 类型断言与守卫

← 返回 TypeScript 教程目录

✈️💬