环境搭建与 tsconfig.json 初识

本节目标

最简单的纯 Node 环境,只需要装一个 typescript:

# 运行环境:已安装 Node.js 16+
# 在任意空文件夹执行:
npm init -y
npm i -D typescript
npx tsc --init          # 生成 tsconfig.json
npx tsc src/index.ts    # 把单个文件编译成 index.js

然后写一个能真正跑起来的文件:

// 运行环境:Node.js 16+ + typescript
// 步骤:保存为 src/index.ts,执行  npx tsc src/index.ts  得到 src/index.js,再  node src/index.js
// 或者直接  npx tsx src/index.ts(tsx 能直接跑 TS,无需先编译)

// 一个带类型的函数
function greeting(name: string): string {
  return `Hello, ${name}`
}

const msg = greeting('TS')
console.log(msg) // 终端输出:Hello, TS

tsconfig.json 是 TS 项目的「总开关」。最影响行为的几个字段:

{
  "compilerOptions": {
    "target": "ES2020",        // 编译产物用哪个 JS 版本(影响是否降级语法)
    "module": "ESNext",        // 用哪种模块规范(ESM / CommonJS)
    "strict": true,            // 严格模式总开关,后面章节细讲,强烈建议开
    "moduleResolution": "bundler",
    "outDir": "dist",          // 编译产物放哪
    "rootDir": "src",          // 源码从哪开始算
    "noEmitOnError": true      // 有类型错误就不输出 JS
  },
  "include": ["src"]
}

一个关键认知盲区:在 Vite 这类前端工程里,.ts 文件是交给 esbuild 转译的,esbuild 只做语法转译、不做类型检查。类型检查是 vue-tsc / tsc --noEmit 单独干的事。所以「项目能 build 过」≠「类型没问题」。

名词解释

tsconfig.json:TypeScript 编译器的配置文件,告诉 tsc「编译哪些文件、按什么规则编译」。它就像项目的「交通规则」,没有它 tsc 不知道从哪下手。include 指定要编译的范围,compilerOptions 指定规则。

strict 模式:"strict": true 是一个「总开关」,它一次性打开了一系列严格检查(noImplicitAny、strictNullChecks 等)。打开后 TS 会「更难糊弄」——很多之前默许的写法会报错。短期痛苦,长期极大提升代码质量。

课后练习

练习 1:把下面代码存成 demo.ts 并 npx tsc --noEmit,会报什么错?为什么?

function double(n: number) {
  return n * 2
}
double('3')

答案:报 Argument of type 'string' is not assignable to parameter of type 'number'。因为 double 的参数被标注为 number,传入字符串 '3' 类型不匹配。这就是 strict 帮你拦下的典型错误。

练习 2:为什么「Vite 项目 build 成功」不代表「类型没问题」?

答案:Vite 默认用 esbuild 转译 TS,esbuild 为了快只去掉类型标注、不检查类型对错。类型检查需要 tsc / vue-tsc 单独跑。所以务必在 CI 或 build 脚本里加上 vue-tsc --noEmit(或 tsc --noEmit)做门禁。

总结

我的观点很明确:strict: true 不是可选项,是必选项。很多团队初期为了「好上手」把它关掉,结果后面写出来的 TS 和披着类型的 JS 没区别,该崩还是崩。类型系统最香的地方恰恰来自 strict 带来的强制判空、禁止隐式 any。另外请建立「检查 ≠ 构建」的心智:构建工具负责快,类型检查工具负责稳,二者要分开跑、都要跑。新手最该养成的习惯,就是每次提交前本地先 tsc --noEmit 一遍——这比任何 lint 规则都值钱。