TypeScript 7 工程起步:安装、tsconfig 与编译流程

系列导航:TypeScript 7 现代开发指南
下一篇:日常类型

TypeScript 的类型检查发生在代码运行前,浏览器和 Node.js 最终执行的仍是 JavaScript。2026 年开始一个 TypeScript 项目时,最重要的不是先背语法,而是固定编译器版本、让编辑器和 CI 使用同一份 tsconfig.json,并根据真实运行环境选择模块配置。

本文以 TypeScript 7.0.2 为基线。TypeScript 7 是使用 Go 实现的原生编译器和语言服务,普通项目仍安装 typescript 包、运行 tsc,但完整构建通常比旧版快 8~12 倍。

一、TypeScript 解决什么问题

JavaScript 允许同一个变量保存不同形态的值,很多错误只能在相关分支真正运行后暴露:

const article = { title: 'TypeScript 7', views: 12 }

console.log(article.titel.toUpperCase())
// 运行到这里才发现 titel 拼错了

TypeScript 在 JavaScript 之上增加静态类型分析:

const article = { title: 'TypeScript 7', views: 12 }

// article.titel.toUpperCase()
// 编译错误:对象上不存在 titel

它擅长提前发现属性拼写、参数数量、空值处理和不可能分支等问题,并让编辑器提供可靠的补全与重构。它不会自动验证网络响应,也不会修复业务逻辑;类型在编译后通常会被擦除。

二、在项目中安装,不要依赖全局版本

创建最小项目:

mkdir ts-app
cd ts-app
npm init -y
npm install --save-dev typescript

确认项目实际使用的版本:

npx tsc --version

把 TypeScript 放在 devDependencies 中有三个好处:

  • package.json 和 lockfile 固定团队、CI 使用的版本;
  • 不会因为开发机的全局 tsc 不同而出现结果漂移;
  • 升级可以作为一次明确的依赖变更进行审查和回滚。

也可以把命令写入脚本:

{
  "scripts": {
    "typecheck": "tsc --noEmit",
    "build": "tsc -p tsconfig.json",
    "typecheck:watch": "tsc --noEmit --watch"
  }
}

之后使用 npm run typecheck,不必要求每个人手动选择编译器。

三、从一个可执行文件开始

创建 src/index.ts

interface User {
  id: string
  name: string
}

function greeting(user: User): string {
  return `你好,${user.name}`
}

console.log(greeting({ id: 'u_001', name: 'Ada' }))

单独给 tsc 传文件适合临时实验:

npx tsc src/index.ts --outDir dist
node dist/index.js

正式项目应让 tsconfig.json 成为唯一配置入口:

npx tsc --init
npx tsc -p tsconfig.json

-p 指定项目配置;在当前目录已有 tsconfig.json 时,直接运行 npx tsc 也会使用它。TypeScript 7 中,命令行构建若发现当前目录存在配置文件,就不能再模糊地同时传入源码路径;确实要忽略配置时需显式使用 --ignoreConfig

四、先区分“编译器默认值”和初始化模板

TypeScript 7 没有配置时采用的关键默认值包括:

  • strict: true
  • module: "esnext"
  • targetesnext 之前的当前稳定 ECMAScript 版本,TypeScript 7.0 对应 ES2025;
  • noUncheckedSideEffectImports: true
  • types: []
  • rootDir: "./"
  • stableTypeOrdering: true,且不能关闭。

tsc --init 写出的则是一份面向通用 Node 开发的推荐模板,会显式包含 module: "nodenext"target: "esnext"strictverbatimModuleSyntaxisolatedModules 等选项。模板不是“所有项目都应该照抄的唯一答案”,仍需根据运行方式调整。

五、构建工具项目使用 bundler 配置

Vite、Rolldown、webpack 或 esbuild 会处理模块和 JavaScript 输出,tsc 通常只做类型检查:

{
  "compilerOptions": {
    "target": "es2022",
    "module": "esnext",
    "moduleResolution": "bundler",
    "strict": true,
    "noEmit": true,
    "isolatedModules": true,
    "verbatimModuleSyntax": true,
    "noUncheckedIndexedAccess": true,
    "exactOptionalPropertyTypes": true,
    "noUncheckedSideEffectImports": true,
    "types": []
  },
  "include": ["src"]
}

这里的职责很清楚:构建工具转译和打包,TypeScript 检查类型。Vite 项目需要客户端环境类型时,可按框架模板把 "vite/client" 加入 types

六、现代 Node.js 项目使用 NodeNext

若 Node.js 直接执行 tsc 输出的 ESM,使用成对的 nodenext

{
  "compilerOptions": {
    "target": "es2022",
    "module": "nodenext",
    "moduleResolution": "nodenext",
    "rootDir": "src",
    "outDir": "dist",
    "strict": true,
    "verbatimModuleSyntax": true,
    "types": ["node"]
  },
  "include": ["src/**/*.ts"]
}

同时安装 Node 类型,并让 package.json 与模块格式一致:

npm install --save-dev @types/node
{
  "type": "module",
  "scripts": {
    "build": "tsc -p tsconfig.json",
    "start": "node dist/index.js"
  }
}

Node ESM 的源码相对导入通常写运行时扩展名,例如 import { add } from './math.js',即使源文件实际叫 math.ts。不要用只适合 bundler 的无扩展名导入测试 Node 产物。

七、理解几个关键选项

1. strict

strict 打开一组相互配合的严格检查,包含 strictNullChecksnoImplicitAny 等。TypeScript 7 已默认开启,但项目仍建议显式写出,方便读者理解契约。

2. types

TypeScript 7 默认 types: [],不再把所有可见 @types 包自动注入全局作用域。需要 Node、测试框架或构建工具全局类型时显式列出;它不会禁止导入普通依赖。

3. rootDiroutDir

TypeScript 7 的 rootDir 默认是项目根目录。希望 src/a.ts 稳定输出到 dist/a.js 时,应明确写 rootDir: "src"outDir: "dist"

4. noEmitnoEmitOnError

  • 构建工具负责输出时使用 noEmit: true
  • tsc 自己输出 JavaScript 时,可使用 noEmitOnError: true,避免类型错误时生成新的产物;
  • --watch 只改变持续监听方式,不改变配置语义。

八、TypeScript 7 升级检查

从较老项目升级时,重点检查:

  1. target: "es5"downlevelIteration 已不再支持;
  2. moduleResolution: "node""node10""classic" 已不再支持,改用 bundlernodenext
  3. baseUrl 已不再支持,paths 可直接相对项目根目录配置,但运行工具也要认识同一别名;
  4. types 默认变为空数组,需要显式列出依赖的全局声明;
  5. rootDir 的新默认值可能改变输出目录结构;
  6. strict 默认开启后会暴露旧代码中的隐式 any 和空值问题。

升级应在独立分支执行类型检查、测试和真实构建。不要用关闭 strict 或堆叠断言来“通过升级”,那只会把风险推回运行时。

九、日常开发流程

一个简单而可靠的循环是:

npm run typecheck:watch
npm run build

编辑器负责即时提示,watch 模式负责项目级检查,CI 再执行一次干净的类型检查和构建。需要标记某一行“预期会报错”时,测试代码优先使用 @ts-expect-error;错误消失后它会反过来提醒你删除过期抑制。@ts-ignore 会无条件隐藏下一行错误,应尽量避免。

小结

新项目应本地安装并固定 TypeScript,通过 npx tsc 或 npm scripts 使用同一版本。tsconfig.json 必须匹配真实运行环境:构建工具项目选择 esnext + bundler + noEmit,现代 Node 项目选择成对的 nodenext。TypeScript 7 的原生编译器提升了速度,也收紧了默认配置和过时选项;升级时应修正环境边界,而不是关闭检查。

官方资料

系列导航:目录 · 下一篇