第63课:TypeScript 环境与配置——安装、tsc、tsconfig.json 详解、编译选项
TypeScript 是 JavaScript 的超集,通过添加静态类型检查将前端开发从“运行时才发现错误”提升到“编译时即发现问题”。要使用 TypeScript,首先需要搭建开发环境:安装 TypeScript 编译器(tsc),并通过 tsconfig.json 配置文件精确控制编译行为。本节课将带你从零开始安装 TypeScript、使用 tsc 编译第一个 .ts 文件,然后逐项拆解 tsconfig.json 中的核心编译选项——从 target、module、strict 到 paths 和 include/exclude,建立对 TypeScript 工程化配置的完整认知。
1. 安装 TypeScript
TypeScript 通过 npm 全局或本地安装。推荐本地安装,因为不同项目可能依赖不同的 TypeScript 版本。
1 | # 全局安装(可在任意终端使用 tsc 命令) |
安装后,通过 npx tsc --version 或 tsc --version 验证。
1 | npx tsc --version |
TypeScript 5.x 是当前主要版本,带来了诸多性能优化和新的类型特性。
2. 第一个 TypeScript 程序
创建文件 hello.ts:
1 | function greet(name: string): string { |
使用 tsc 编译:
1 | npx tsc hello.ts |
编译后会生成 hello.js 文件,内容是移除了类型注解的纯 JavaScript 代码:
1 | function greet(name) { |
注意:默认情况下,tsc 即使遇到类型错误,也仍然会输出 JavaScript 文件(可通过 noEmitOnError 选项改变此行为)。类型检查与代码生成是独立的。
3. tsconfig.json:TypeScript 项目的核心配置
在实际项目中,我们不会为每个文件手动执行 tsc,而是通过 tsconfig.json 定义整个项目的编译选项。在项目根目录执行:
1 | npx tsc --init |
会生成一个带有完整注释的 tsconfig.json 文件。下面逐项拆解最关键的部分。
3.1 顶层选项
1 | { |
| 选项 | 说明 |
|---|---|
include |
指定哪些文件应被包含在编译中。支持 glob 模式。 |
exclude |
指定哪些文件应被排除。默认排除 node_modules。 |
files |
显式指定要编译的文件列表(不支持 glob)。与 include 互斥,很少用。 |
如果没有 include,tsc 默认编译所有 .ts、.tsx、.d.ts 文件(排除 node_modules)。
4. 核心编译选项详解
所有编译选项位于 compilerOptions 对象中。以下分组说明最常用的配置项。
4.1 目标与模块
| 选项 | 说明 | 推荐值 |
|---|---|---|
target |
编译后 JavaScript 的语言版本。 | ES2022 或 ESNext |
module |
模块系统。CommonJS(Node)、ESNext(现代浏览器/打包工具)、Node16(Node ESM)。 |
ESNext |
moduleResolution |
模块解析策略:node(经典)、bundler(现代打包工具,推荐)。 |
bundler |
lib |
包含哪些内置类型定义(如 DOM、ES2022)。默认根据 target 自动推导。 |
["ES2022", "DOM"] |
1 | { |
moduleResolution: "bundler" 是 TypeScript 5.x 推荐的现代解析策略,专为配合 Webpack、Vite、Rollup 等打包工具设计,支持无扩展名导入和 exports 字段解析。
4.2 严格模式与类型检查
strict 是一个元选项,开启后自动启用以下所有严格检查:
1 | { |
strict: true 等价于同时启用:
| 子选项 | 说明 |
|---|---|
strictNullChecks |
null 和 undefined 不能赋值给其他类型。这是最重要的严格选项。 |
strictFunctionTypes |
函数参数类型检查更严格(逆变)。 |
strictBindCallApply |
bind、call、apply 的参数类型检查。 |
strictPropertyInitialization |
类的属性必须初始化(在构造函数中或声明时)。 |
noImplicitAny |
禁止隐式 any 类型。 |
noImplicitThis |
禁止隐式 any 类型的 this。 |
alwaysStrict |
生成 "use strict"。 |
**推荐始终开启 strict: true**。如果项目从 JavaScript 逐步迁移,可以暂时关闭某些严格选项,但应尽快补全类型后重新开启。
4.3 路径别名与基础路径
1 | { |
paths 允许定义模块路径别名,配合打包工具(Vite、Webpack)的对应配置,实现 import { Button } from '@components/Button' 而非 import { Button } from '../../../components/Button'。baseUrl 是路径解析的基础目录。
重要:TypeScript 仅负责类型检查——编译时不会转换路径别名。实际路径解析需要打包工具(如 Vite 的 resolve.alias 或 Webpack 的 resolve.alias)来完成。两者必须保持一致。
4.4 输出控制
| 选项 | 说明 | 常用值 |
|---|---|---|
outDir |
输出目录。 | "dist" |
rootDir |
源码根目录。通常设为 "src"。 |
"src" |
declaration |
是否生成 .d.ts 类型声明文件(库开发时必开)。 |
true |
declarationMap |
生成声明文件的 Source Map(方便 IDE 跳转源码)。 | true |
sourceMap |
生成 .js.map 文件,调试时映射到原始 TypeScript。 |
true |
noEmit |
仅做类型检查,不输出任何文件(适合 tsc --noEmit)。 |
true |
noEmitOnError |
有类型错误时不输出文件。 | true(CI 推荐) |
1 | { |
4.5 其他重要选项
| 选项 | 说明 | 推荐值 |
|---|---|---|
esModuleInterop |
允许 import 导入 CommonJS 模块。 |
true |
allowSyntheticDefaultImports |
允许 import React from 'react' 这种写法(类型检查用)。 |
true |
forceConsistentCasingInFileNames |
强制文件名大小写一致(避免跨平台问题)。 | true |
skipLibCheck |
跳过声明文件(.d.ts)的类型检查,加快编译速度。 |
true |
isolatedModules |
将每个文件视为独立模块(与打包工具行为一致)。 | true |
resolveJsonModule |
允许导入 .json 文件。 |
true |
5. tsconfig.json 的继承与扩展
extends 属性可以从另一个配置文件继承选项,覆盖或扩展特定字段。
1 | { |
TypeScript 社区有一些流行的基础配置,如 @tsconfig/node20、@tsconfig/vite-react。使用它们可以快速获得最佳实践配置:
1 | npm install -D @tsconfig/node20 |
1 | { |
6. 在 Vite 项目中使用 TypeScript
Vite 默认支持 TypeScript,只需将文件后缀改为 .ts 或 .vue 中的 <script lang="ts">。Vite 内部使用 esbuild 进行转译(仅移除类型,不做类型检查),速度极快。
1 | pnpm create vite my-app --template vue-ts |
运行 tsc --noEmit 进行单独的类型检查(因为 esbuild 不做类型检查):
1 | // package.json |
CI 流程中应在 build 之前执行 typecheck,确保类型安全。
课后练习
一、概念自测(选择题 / 填空题)
(单选)
tsconfig.json中的strict: true会启用多个严格检查选项。以下哪个选项不包含在strict: true的范围内?
A.strictNullChecks
B.noImplicitAny
C.noUnusedLocals
D.strictFunctionTypes(单选) 关于
esModuleInterop选项,以下描述正确的是?
A. 它允许 TypeScript 代码使用require。
B. 它允许使用import语法导入 CommonJS 模块。
C. 它负责生成 CommonJS 格式的输出。
D. 它决定模块解析策略。(填空) 要使 TypeScript 编译器在遇到类型错误时不输出 JavaScript 文件,应设置
compilerOptions中的______为true。(多选) 以下哪些文件会影响 TypeScript 项目的编译行为?
A.tsconfig.json
B.package.json
C.tsconfig.node.json
D..d.ts类型声明文件
二、AI 编程任务:编写面向 AI 的提示词
场景:你需要为一个新的 Node.js 项目配置 TypeScript。要求如下:
- 目标
target为ES2022。 - 模块系统
module为Node16。 - 开启所有严格检查(
strict: true)。 - 源码目录
src,输出目录dist。 - 生成类型声明文件。
- 排除
node_modules和dist。 - 启用
esModuleInterop、skipLibCheck和forceConsistentCasingInFileNames。
任务要求:请写出一段完整的中文提示词,发送给 AI,使其生成符合上述要求的 tsconfig.json 文件。提示词中需明确指定所有要求项。
三、Agent 模式下的提示词示例
你是一个资深前端开发 Agent。请为一个 Node.js 后端项目创建 TypeScript 配置文件。需要创建:
tsconfig.json:设置compilerOptions为target: "ES2022"、module: "Node16"、moduleResolution: "Node16"、strict: true、outDir: "./dist"、rootDir: "./src"、declaration: true、sourceMap: true、esModuleInterop: true、skipLibCheck: true、forceConsistentCasingInFileNames: true。设置include: ["src/**/*.ts"]、exclude: ["node_modules", "dist"]。package.json:添加"type": "module"(与Node16模块兼容),添加脚本"build": "tsc"、"typecheck": "tsc --noEmit"、"dev": "node --loader ts-node/esm src/main.ts"。.gitignore:添加dist/和node_modules/。
所有配置遵循 TypeScript 5.x 最佳实践。完成后列出所有文件内容。
课后练习答案
一、概念自测答案
C
- 解析:
noUnusedLocals(未使用的局部变量)和noUnusedParameters(未使用的参数)是独立的检查选项,不在strict: true范围内,但推荐在严格项目中同时开启。
- 解析:
B
- 解析:
esModuleInterop: true允许使用import语法导入 CommonJS 模块(如import express from 'express'),并在类型上更宽松地处理默认导入。
- 解析:
noEmitOnError- 解析:
noEmitOnError: true在有类型错误时阻止输出 JavaScript 文件。
- 解析:
A、C、D
- 解析:
tsconfig.json是主配置文件;tsconfig.node.json常被 Vite 等项目用于 Node 端配置(如 vite.config.ts 的类型检查);.d.ts文件提供类型声明。package.json本身不影响 TypeScript 编译行为(除非使用了"types"字段指定入口类型文件)。
- 解析:
二、AI 编程任务参考答案(提示词示例)
示例提示词:
“请生成一个 Node.js TypeScript 项目的tsconfig.json文件。要求:
compilerOptions中设置target: "ES2022"、module: "Node16"、moduleResolution: "Node16"、strict: true、outDir: "./dist"、rootDir: "./src"、declaration: true、sourceMap: true、esModuleInterop: true、skipLibCheck: true、forceConsistentCasingInFileNames: true。include: ["src/**/*.ts"],exclude: ["node_modules", "dist"]。- 使用 JSON 格式,键名带双引号。直接输出完整文件内容。”