tsc 完全指南:TypeScript 编译器的命令行实战

本文系统讲解 TypeScript 编译器 tsc:安装、编译目标(target)、模块系统(module)、tsconfig.json 配置、watch 模式与声明文件生成,帮你真正掌控 TS 编译过程。

最佳实践
类型结构与组件组合插画

tsc 是 TypeScript 的官方编译器:tsc app.ts 编译单文件,项目级编译由 tsconfig.json 驱动(tsc 无参数即读取它)。核心配置三件:target(输出 JS 版本)、module(模块格式)、strict(严格检查);开发用 tsc --watch,CI 用 tsc --noEmit 做纯类型检查。

为什么值得学 tsc CLI

现代工具链(Vite、tsx、Bun)把编译藏在了幕后,但理解 tsc 依然必要:类型检查的最终裁判是它(那些快工具都不做检查)、库的声明文件(.d.ts)由它生成、构建报错时只有懂 tsconfig 才能排查。

安装与第一个编译

npm install -g typescript        # 或项目内 npm i -D typescript
tsc hello.ts                     # 产出 hello.js
tsc hello.ts --target es2022     # 指定输出版本
tsc --noEmit src/index.ts        # 只检查不输出

项目内安装 + npx 调用是团队标准做法(版本锁定,避免全局版本漂移)。

target:编译到哪个 JS 版本

--target 决定输出 JavaScript 的语法级别:es5(古老浏览器)、es2016(Node 8+)、es2022(Node 18+/现代浏览器)、esnext(最新)。Node.js 后端项目用 es2022 起步即可——async/await、可选链、空值合并全部原生保留,输出干净可读。

module:模块系统的选择

这是最容易配错的一项:

  • commonjs:输出 require/module.exports,传统 Node 项目;
  • nodenext:遵循 package.json 的 "type" 字段,Node ESM 项目的正确选择;
  • esnext:纯 ESM 输出,供打包器(Vite/webpack)二次处理;
  • preserve(TS 5.4+):保留源码中的模块写法。

配套规则:用 nodenext 时 import 相对路径要带 .js 扩展名(指向编译后的文件名),这不是 bug 而是 Node ESM 的规范要求。

tsconfig.json:项目的编译中枢

{
  "compilerOptions": {
    "target": "es2022",
    "module": "nodenext",
    "outDir": "./dist",
    "rootDir": "./src",
    "strict": true,
    "declaration": true,
    "sourceMap": true,
    "skipLibCheck": true
  },
  "include": ["src/**/*"],
  "exclude": ["node_modules", "dist"]
}

strict: true 开启全部严格检查(新项目的底线);declaration 生成 .d.ts(发布库必开);skipLibCheck 跳过 node_modules 里的声明检查,编译提速明显且避开第三方声明错误。

watch 模式与增量编译

tsc --watch              # 文件变化自动重编译
tsc --build              # 增量构建(生成 .tsbuildinfo 缓存)

大项目用 --build 模式的增量编译:只有变化的文件及其依赖被重新处理,二次编译从分钟级降到秒级。项目引用(project references)进一步支持 monorepo 的分包增量构建。

常见问题(FAQ)

Q:tsc 编译慢怎么优化?

三板斧:skipLibCheck: true(跳过第三方声明检查,收益最大)、--build 增量模式、include 精确圈定源码范围(别把测试和脚本目录扫进来)。还要更快就用 tsx/esbuild 负责转译、tsc 只做 CI 类型检查。

Q:编译报错但工具链(Vite/tsx)能跑,听谁的?

听 tsc 的。Vite/tsx/esbuild 只做转译不做类型检查——它们能跑不代表类型正确。CI 里必须有 tsc --noEmit 这关,类型安全才有保障。

Q:rootDir 报错"文件不在 rootDir 下"怎么处理?

include 中混入了 src 之外的文件(典型是把测试目录包了进来)。把测试排除或放宽 rootDir 到公共父目录;monorepo 场景改用 project references 分包编译。


参考文档

本文依据公开文档整理,示例需按项目依赖版本验证;不将文档中的性能描述视为本项目实测结果。

延伸阅读

获取专属方案

联系我们

加入社区

微信扫码
加入官方交流群

立即体验

在线开通,按量计费,真正的云服务!

立即开始

选择观测云版本

代码托管平台