TypeScript 编译与调试完全指南
摘要总结: TypeScript 作为 JavaScript 的静态类型超集,不仅提供了类型安全,还构建了完善的编译工具链和调试能力。本文系统梳理 TypeScript 项目的编译与调试全流程,涵盖 TSC 编译器使用、tsconfig.json 各场景配置(单体项目、Monorepo 多包项目)、source map 浏览器调试、ESLint 静态检查与 Jest 单元测试等工程实践。通过对编译选项(strict、module、moduleResolution、incremental 等)的详细解读,以及 React+Vite、Node.js、npm 库等典型项目配置示例,帮助读者建立对 TypeScript 编译体系的完整认知。掌握这些核心技能,能够帮助开发者更高效地构建和维护高质量的 TypeScript 应用。
编写代码只是开发工作的起点,真正决定项目质量的是后续的编译与调试环节。TypeScript 作为 JavaScript 的静态类型超集,不仅带来了类型安全,更提供了强大的编译工具和调试能力,让我们能够更高效地构建和维护可靠的应用程序。
本文将对 TypeScript 项目的编译与调试进行梳理,包括编译工具 TSC 的使用、编译选项的配置、调试工具的使用等。
1. TypeScript 编译配置与 tsconfig.json
TSC(TypeScript Compiler)是 TypeScript 官方提供的编译工具,负责将 TypeScript 代码(.ts 或 .tsx)转换为 JavaScript 代码(.js 或 .jsx)。
虽然你可以直接在终端运行 tsc 命令来编译单个文件,但在实际项目中,我们通常需要处理大量文件。为了提高编译命令的复用性和可维护性,TypeScript 提供了配置文件的方式来管理编译设置:
- 配置文件:使用
tsconfig.json文件集中管理待编译文件路径、编译选项和输出路径等。你可以通过tsc --init命令快速生成一个默认配置文件,然后根据项目需求进行调整。 - 配置位置:通常将
tsconfig.json放在项目根目录下。对于 Monorepo 项目结构,每个子项目可以拥有独立的配置文件,实现更精细的编译控制。
1.1 tsconfig.json 核心配置梳理
以下是一个生产环境常用的 tsconfig.json 配置示例,包含了 TypeScript 核心编译选项的详细注释说明:
{
/*
* ============================================
* 编译信息配置
* ============================================
*/
"compilerOptions": {
/*
* 基本选项
*/
// 目标 ECMAScript 版本,指定编译后的 JavaScript 代码的 ECMAScript 版本
// 推荐值:
// - "ES5":兼容性最佳,支持所有现代浏览器
// - "ES2020":现代浏览器支持,性能更好
// - "ESNext":最新特性,但兼容性可能有问题
"target": "ES2020",
// 模块系统,指定编译后代码使用的模块化方案
// 推荐值:
// - "CommonJS":Node.js 默认,使用 require/module.exports
// - "ESNext"/"ES2020":现代浏览器支持,使用 import/export
// - "UMD":兼容 CommonJS 和 AMD
// - "System":SystemJS 模块加载器
"module": "ESNext",
// 允许编译的 JavaScript 文件目录,默认为 ["src"]
// 支持 glob 模式,如 "src/**/*.ts"
"rootDir": "./src",
// 编译输出目录,编译后的 .js 文件会放在此目录
"outDir": "./dist",
// 指定输出文件目录结构,不设置则所有文件平铺在 outDir 中
// 保持源码目录结构:"preserve";全部平铺:"flatten"
"rootDirs": ["src", "tests"],
/*
* 类型检查选项(strict 相关)
* 强烈建议开启所有 strict 相关选项,以获得最佳类型安全
*/
// 启用所有严格类型检查选项,等同于同时启用以下所有选项
// 强烈推荐:true,生产项目必备
"strict": true,
// 严格空值检查,启用后,null 和 undefined 不能赋值给其他类型
// 例如:let name: string = null; // 报错
"strictNullChecks": true,
// 严格模式下的函数类型检查,包括参数个数和返回值类型
"strictFunctionTypes": true,
// 严格属性初始化检查,类属性必须在构造函数中初始化
"strictPropertyInitialization": true,
// 严格 this 类型检查,函数调用时 this 被视为 any
"strictCallApply": true,
// noImplicitAny:禁止隐式 any 类型,必须显式声明类型
// 推荐:true,避免类型不明确导致的 bug
"noImplicitAny": true,
// noImplicitThis:禁止 this 隐式 any 类型
"noImplicitThis": true,
// 始终使用严格相等检查,禁用 == 和 !=,强制使用 === 和 !==
"strictEquality": true,
// 禁用 override 关键字(TS 4.3+),确保方法确实重写了父类方法
"noOverride": false,
/*
* 输出控制选项
*/
// 生成 .d.ts 声明文件,用于为库提供类型定义
// 发布 npm 包时必须开启
"declaration": true,
// 声明文件输出目录
"declarationDir": "./dist/types",
// 生成 source map 文件,用于调试
// 开发环境建议开启,生产环境可根据需要开启
"sourceMap": true,
// 合并所有声明文件为一个 .d.ts 文件
"declarationMap": true,
// 移除代码中的注释
"removeComments": true,
// 不输出 .js 文件,仅做类型检查
// 用于配合 watch 模式进行类型检查
"noEmit": false,
// 发生错误时不生成 .js 文件
// 确保代码质量,防止生成有问题的输出
"noEmitOnError": true,
// 导入导出修饰符是否可见,如 private、protected、public
"stripInternal": true,
/*
* 模块解析选项
*/
// 模块解析策略
// - "node":Node.js 风格解析(CommonJS)
// - "node16":Node.js 16+ 风格,支持精确的子路径导出
// - "nodenext":Node.js 最新风格,与 node16 类似但更严格
// - "bundler":适用于 webpack、vite 等打包工具
"moduleResolution": "bundler",
// 解析模块时的基础路径,通常配合 baseUrl 使用
// 如:baseUrl 为 "./src",则 import from "@utils" 解析为 "./src/utils"
"baseUrl": "./src",
// 路径映射,允许为模块路径设置别名
// 使用示例:import { Button } from "@components/Button"
"paths": {
"@/*": ["./*"], // @ 指向 src 目录
"@components/*": ["./components/*"], // @components 指向 components 目录
"@utils/*": ["./utils/*"], // @utils 指向 utils 目录
"@hooks/*": ["./hooks/*"], // @hooks 指向 hooks 目录
"@services/*": ["./services/*"], // @services 指向 services 目录
"@types/*": ["../shared-types/*"] // @types 指向共享类型目录
},
// 允许从不严格的导出(如 default export)导入默认导出
// 兼容 CommonJS 模块
"allowSyntheticDefaultImports": true,
// 允许 import x from 'x' 形式的导入,即使模块没有默认导出
// 需要配合 moduleResolution 使用
"esModuleInterop": true,
// 不解析符号链接,直接使用链接指向的文件
// Node.js 项目通常需要开启
"preserveSymlinks": true,
// 允许导入 JSON 文件作为模块
"resolveJsonModule": true,
// 启用所有 JAR 文件作为可读模块(Java 互操作)
"enableJavaScript": true,
/*
* 语言和环境选项
*/
// 指定允许的库文件类型,如 DOM、ESNext 等
// 自动包含 @types/node 和目标环境的类型定义
"lib": ["ES2020", "DOM", "DOM.Iterable"],
// JSX 语法支持,用于 React/Preact 等框架
// - "react":生成 React.createElement 代码
// - "react-jsx":生成 React JSX runtime 代码(React 17+ 推荐)
// - "preserve":保留 JSX,不编译,由构建工具处理
// - "react-native":保留 JSX,由 React Native 处理
"jsx": "react-jsx",
// JSX 工厂函数,用于创建 JSX 元素
"jsxFactory": "React.createElement",
// JSX Fragment 工厂函数,用于创建 JSX Fragment
"jsxFragmentFactory": "React.Fragment",
// 启用实验性装饰器支持(TC39 提案)
// 开启后可以使用 @decorator 语法
"experimentalDecorators": true,
// 启用装饰器元数据(需要 experimentalDecorators)
// 允许在运行时通过 Reflect.metadata 获取装饰器元数据
"emitDecoratorMetadata": true,
// 指定 JSON 模块的根据点
"interactive": true,
// 启用对 JSX 文件的引用(TS 4.5+)
"jsxRaw": true,
/*
* 诊断和报告选项
*/
// 报告未使用的标签(用于 React)
"noUnusedLocals": true,
// 报告未使用的参数
"noUnusedParameters": true,
// 报告隐式类型转换可能丢失数据的警告
"noImplicitReturns": true,
// 报告 switch 语句中缺少 break 的 case
"noFallthroughCasesInSwitch": true,
// 报告可达代码错误,如 return 后的代码
"allowUnreachableCode": false,
// 报告标记为 @deprecated 的代码使用情况
"noImplicitOverride": true,
// 报告未使用的标签(TS 4.5+)
"noUncheckedIndexedAccess": true,
// 报告可能与 BigInt 冲突的位运算
"noBitwise": true,
// 增量编译,保存编译信息以加速后续编译
// 开启后会生成 .tsbuildinfo 文件
"incremental": true,
// 增量编译信息文件路径
"tsBuildInfoFile": "./node_modules/.cache/tsbuildinfo",
/*
* 代码生成选项
*/
// 生成 ES2015 模块的调用,启用后会将 ES module 转为 CommonJS
"esModuleInterop": true,
// 生成的模块使用 const 代替 let
"assumeChangesOnlyAffectDirectDependencies": true,
// 不允许 TS 从 @types 包引入额外的类型
// 用于控制类型定义的来源
"skipDefaultLibCheck": true,
// 跳过所有 .d.ts 文件的类型检查
// 显著提升编译速度,但可能影响类型安全
// 库开发时不推荐开启
"skipLibCheck": true,
// 指定输出字符集
"charset": "utf8",
// 格式化输出,使用更易读的格式
"pretty": true,
// 指定编译时使用的 Watch 选项文件
"watchOptions": {
"watchFile": "useFsEvents",
"watchDirectory": "useFsEvents",
"fallbackPolling": "dynamicPriority"
}
},
/*
* ============================================
* 文件包含配置
* ============================================
*/
// 指定需要编译的文件,支持 glob 模式
// 默认包含所有 .ts, .tsx 文件和所有 .d.ts 文件
"include": [
"src/**/*.ts", // 源代码
"src/**/*.tsx", // React/Preact 组件
"src/**/*.d.ts", // 类型声明文件
"tests/**/*.ts", // 测试代码
"tests/**/*.tsx" // 测试组件
],
// 指定不需要编译的文件
"exclude": [
"node_modules", // 依赖目录(默认排除)
"dist", // 输出目录
"build", // 构建输出目录
"coverage", // 测试覆盖率报告
"*.spec.ts", // 测试文件
"*.test.ts", // 测试文件
"**/*.spec.tsx", // React 测试文件
"**/*.test.tsx", // React 测试文件
"**/__tests__/**", // 测试目录
"**/__mocks__/**", // Mock 目录
"*.config.js", // 配置文件
"*.config.ts", // 配置文件
".vscode", // VSCode 配置
".idea" // IDEA 配置
],
// 指定需要编译的指定文件(优先级高于 include)
"files": [
"src/index.ts"
],
// ============================================
// 引用配置(用于 Monorepo 项目)
// ============================================
// 引用其他 TypeScript 项目,实现类型共享和增量编译
"references": [
{ "path": "../shared" },
{ "path": "../utils" }
],
// 继承其他 tsconfig 配置
// 如:继承根目录的基础配置
"extends": "../tsconfig.base.json",
// 启用复合项目,支持被其他项目引用
// 需要配合 references 使用
"composite": true,
// 启用增量编译
"incremental": true
}1.2 常用 TypeScript 配置组合
了解了上述核心配置选项后,我们来看看不同项目场景下的实际应用。以下是针对常见项目类型的推荐配置组合。
以下是针对不同项目类型的推荐配置组合:
1、React + Vite 项目:
{
"compilerOptions": {
"target": "ES2020",
"useDefineForClassFields": true,
"lib": ["ES2020", "DOM", "DOM.Iterable"],
"module": "ESNext",
"skipLibCheck": true,
// 模块解析
"moduleResolution": "bundler",
"allowImportingTsExtensions": true,
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
// JSX
"jsx": "react-jsx",
// 严格模式
"strict": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"noFallthroughCasesInSwitch": true
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}2、Node.js + Express 项目:
{
"compilerOptions": {
"target": "ES2020",
"module": "CommonJS",
"lib": ["ES2020"],
"outDir": "./dist",
"rootDir": "./src",
// 类型检查
"strict": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
// 模块解析
"moduleResolution": "node",
"esModuleInterop": true,
"resolveJsonModule": true,
// 输出
"declaration": true,
"declarationMap": true,
"sourceMap": true,
// 实验性功能
"experimentalDecorators": true,
"emitDecoratorMetadata": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist", "**/*.spec.ts"]
}3、npm 库开发:
{
"compilerOptions": {
"target": "ES2020",
"module": "ESNext",
"lib": ["ES2020", "DOM"],
"declaration": true,
"declarationDir": "./types",
"declarationMap": true,
"sourceMap": true,
"outDir": "./dist",
"rootDir": "./src",
// 严格模式
"strict": true,
// 模块解析
"moduleResolution": "node",
"esModuleInterop": true,
"allowSyntheticDefaultImports": true,
// 代码生成
"removeComments": true,
"noEmitOnError": true
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}2. 大型项目的模块化配置:extends 与 references
在大型应用项目中,我们通常采用 Monorepo 仓库结构,将项目划分为多个独立的子项目(如 packages/web、packages/api、packages/shared 等)。每个子项目都有独立的 tsconfig.json 文件,用于配置该子项目的编译选项。
为了在保持各子项目独立性的同时,实现配置复用和类型共享,TypeScript 提供了 References(引用) 和 Extends(继承) 配置机制。
2.1 核心概念解析
1、references(项目引用)
references 选项用于声明当前项目依赖的其他 TypeScript 项目。通过项目引用,可以实现:
| 功能 | 说明 |
|---|---|
| 类型共享 | 被引用的项目类型可以被当前项目使用,实现跨项目的类型安全 |
| 增量编译 | TypeScript 可以智能地只编译发生变化的项目,提升编译效率 |
| 依赖管理 | 明确项目间的依赖关系,便于构建工具进行优化 |
2、composite(复合项目)
当项目需要被其他项目引用时,必须启用 composite: true。启用后,TypeScript 会:
| 功能 | 说明 |
|---|---|
| 声明文件 | 自动生成 .d.ts 声明文件 |
| 增量信息 | 生成 .tsbuildinfo 增量编译信息文件 |
| 安全引用 | 确保项目可以被其他项目安全引用 |
3、extends(配置继承)
extends 选项用于继承另一个 tsconfig.json 文件的配置。这是实现配置复用的核心机制,与 references 配合使用可以构建灵活的配置体系:
| 功能 | 说明 |
|---|---|
| 配置继承 | 子项目通过 extends 继承根目录或父项目的通用配置,避免重复定义相同的编译选项 |
| 配置覆盖 | 子项目可以在继承的基础上,通过 compilerOptions 覆盖或扩展特定选项,实现项目特定的配置需求 |
| 配置分层 | 支持多级继承(如 extends: "../../tsconfig.json"),构建清晰的配置层次结构 |
2.2 extends 与 references 的区别
| 特性 | extends | references |
|---|---|---|
| 作用对象 | 配置选项(compilerOptions 等) | TypeScript 项目(编译单元) |
| 主要目的 | 配置复用和继承 | 项目依赖和类型共享 |
| 使用场景 | 统一编译规则、减少配置重复 | 跨项目类型引用、增量编译优化 |
| 配置方式 | 字符串路径(如 "../../tsconfig.json") | 对象数组(如 [{ "path": "../shared" }]) |
| 是否必需 | 可选,但强烈推荐用于配置复用 | 仅在需要引用其他项目时使用 |
3. Monorepo 项目配置实践
在大型应用项目中,业界推荐的 Monorepo 目录结构示意如下:
monorepo/
├── tsconfig.base.json # 根配置(基础配置)
├── packages/
│ ├── shared/ # 共享库项目
│ │ ├── tsconfig.json
│ │ └── src/
│ ├── web/ # Web 前端项目
│ │ ├── tsconfig.json
│ │ └── src/
│ └── api/ # API 后端项目
│ ├── tsconfig.json
│ └── src/
└── package.json3.1 根配置(tsconfig.base.json)
根配置应该只包含通用的 compilerOptions,不包含具体文件。
{
"compilerOptions": {
// 严格模式(强烈推荐开启)
"strict": true,
// 跳过库文件检查,提升编译速度
"skipLibCheck": true,
// 增量编译
"incremental": true
}
}3.2 共享库项目(packages/shared/tsconfig.json)
共享库需要被其他项目引用,必须启用 composite。
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
// 必须启用 composite,使该项目可被其他项目引用
"composite": true,
// 输出目录
"outDir": "./dist",
// 根目录
"rootDir": "./src"
},
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}3.3 Web 前端项目(packages/web/tsconfig.json)
Web 项目需要浏览器环境支持,配置略有不同。
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
// Web 环境配置
"lib": ["DOM", "DOM.Iterable", "ES2020"],
"jsx": "react-jsx",
// 输出目录
"outDir": "./dist",
"rootDir": "./src"
},
// 引用 shared 项目,实现类型共享
"references": [
{ "path": "../shared" }
],
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}3.4 API 后端项目(packages/api/tsconfig.json)
Node.js 后端项目使用 CommonJS 模块系统。
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
// Node.js 环境配置
"lib": ["ES2020"],
"module": "CommonJS",
"moduleResolution": "node",
// 输出目录
"outDir": "./dist",
"rootDir": "./src"
},
// 引用 shared 项目
"references": [
{ "path": "../shared" }
],
"include": ["src/**/*"],
"exclude": ["node_modules", "dist"]
}3.5 最佳实践总结
在 Monorepo 项目中,extends 与 references 的最佳实践如下:
配置分层原则:
| 配置类型 | 说明 |
|---|---|
| 根配置(tsconfig.base.json) | • 放置所有项目通用的配置选项 • 不包含 files、include、exclude• 只定义 compilerOptions |
| 子项目配置 | • 通过 extends 继承根配置• 只覆盖自己需要的特定选项 • 使用 references 声明对其他项目的依赖 |
| composite 启用规则 | • 只有需要被其他项目引用的项目才启用 • 通常是共享库(shared) • 应用项目(web、api)通常不需要启用 |
路径别名配置建议:
业界不推荐在 tsconfig.json 中使用 paths 进行跨包路径别名配置,原因如下:
- 构建工具(webpack、vite)有自己的模块解析机制
paths在引用项目时可能不生效- 增加了配置的复杂性
推荐做法:
pnpm/Yarn workspace:使用 workspace 协议直接引用
json// packages/web/package.json { "dependencies": { "@monorepo/shared": "workspace:*" } }构建工具配置:在 webpack/vite 中配置路径别名
javascript// vite.config.ts resolve: { alias: { '@shared': path.resolve(__dirname, '../shared/src') } }TypeScript 路径映射:仅用于 IDE 智能提示(在非 composite 项目中)
json{ "compilerOptions": { "baseUrl": ".", "paths": { "@shared/*": ["packages/shared/src/*"] } } }
增量编译命令:
使用 tsc --build 命令进行增量编译:
# 编译所有项目(按依赖顺序)
tsc --build
# 强制重新编译所有项目
tsc --build --force
# 清理所有编译产物
tsc --build --clean多级配置继承示例:
对于更复杂的项目结构,可以创建中间层配置:
// packages/frontend/tsconfig.base.json(前端项目通用配置)
{
"extends": "../../tsconfig.base.json",
"compilerOptions": {
"lib": ["DOM", "DOM.Iterable"]
}
}
// packages/web/tsconfig.json(Web 项目配置)
{
"extends": "../frontend/tsconfig.base.json",
"compilerOptions": {
"jsx": "react-jsx"
},
"references": [{ "path": "../shared" }]
}3. 调试代码
在 TypeScript 项目中,代码最终会被编译为 JavaScript 运行。调试时,我们更倾向于直接调试 TypeScript 源代码,因为:
| 编译后 JavaScript 调试的问题 | 影响 |
|---|---|
| 变量名、函数名会被压缩混淆 | 无法直接查看有意义的变量值和调用栈 |
| 编译产物包含类型擦除和填充代码 | 调试时出现冗余代码,干扰调试流程 |
为了在浏览器中直接调试 TypeScript 源码,我们可以通过前端构建工具(如 Vite、Rsbuild、webpack)开启 source map 功能。启用后,浏览器调试器会直接显示原始的 TypeScript 代码,而非编译后的 JavaScript。
4. 引入扩展工具
4.1. 静态检查工具 ESLint
TypeScript 虽然有自己的类型检查机制,但无法检查代码是否符合规范。因此,我们需要借助可配置化工具,将工程中的代码规范配置到工具中,来自动化检查代码是否符合规范,以减少人工 review 的工作量。
ESLint 是一个自动化的静态代码检查工具,能用于检测代码是否符合指定的编码规范。它可以帮助开发者发现代码中的问题,如未使用的变量、未定义的函数、无效的语法等。
4.2. 单测工具 Jest
Jest 是一个流行的 JavaScript 单测框架,它提供了简单、快速的测试编写和执行方式。Jest 支持 TypeScript,并且可以与 TypeScript 代码无缝集成。
4.2.1 安装依赖
在 TypeScript 项目中使用 Jest 需要安装以下依赖:
# 核心依赖
npm install --save-dev jest typescript ts-jest @types/jest
# 如果使用 ES 模块
npm install --save-dev @types/node4.2.2 配置 Jest
创建 Jest 配置文件 jest.config.ts:
import type { Config } from 'jest';
const config: Config = {
preset: 'ts-jest',
testEnvironment: 'node',
roots: ['<rootDir>/src'],
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
moduleFileExtensions: ['ts', 'js', 'json', 'node'],
transform: {
'^.+\.tsx?$': 'ts-jest',
},
coverageDirectory: 'coverage',
collectCoverageFrom: ['src/**/*.ts', '!src/**/*.d.ts'],
};
export default config;4.2.3 编写测试用例
创建一个简单的 TypeScript 文件 src/math.ts:
export const add = (a: number, b: number): number => a + b;
export const subtract = (a: number, b: number): number => a - b;创建对应的测试文件 src/math.test.ts:
import { add, subtract } from './math';
describe('math functions', () => {
test('add should return the sum of two numbers', () => {
expect(add(1, 2)).toBe(3);
expect(add(-1, 1)).toBe(0);
});
test('subtract should return the difference of two numbers', () => {
expect(subtract(5, 3)).toBe(2);
expect(subtract(3, 5)).toBe(-2);
});
});4.2.4 运行测试
在 package.json 中添加测试脚本:
{
"scripts": {
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage"
}
}运行测试:
npm test4.2.5 高级特性
Jest 还提供了一些高级特性,如异步测试、模拟函数、快照测试等,可以满足各种复杂的测试需求。更多详细信息请可参考 Jest 官方文档。
- 异步测试:支持 Promise 和 async/await
- 模拟函数:使用
jest.fn()创建模拟函数 - 快照测试:生成组件或数据结构的快照
- 测试覆盖率:自动生成覆盖率报告
5. 结语
TypeScript 的价值不仅在于静态类型检查带来的代码提示和编译时错误发现,更在于其完善的编译体系、调试能力和配套的质量保障工具。
在实际项目中,我们需要关注以下几个层面:
| 关注层面 | 说明 |
|---|---|
| 配置管理 | 合理规划 tsconfig.json 的分层结构,无论是单体项目还是 Monorepo 架构,都能通过 extends 和 references 实现配置的复用与独立定制。 |
| 代码质量 | ESLint 和 Prettier 与 TypeScript 相辅相成,前者保障代码规范,后者统一代码风格,共同减少团队协作中的摩擦。 |
| 调试体验 | 善用 source map 等调试技术,在保持源码可读性的同时,不牺牲生产环境的性能。 |
| 测试覆盖 | 完善的测试用例是类型检查之外的最后一道防线,Jest 等工具让我们能够更自信地进行代码重构。 |
掌握这些编译与调试的核心技能,能够帮助我们更高效地构建和维护高质量的 TypeScript 应用。希望本文能为你的项目实践提供一些参考和帮助。