TypeScript 遗留代码重构:从 A 到 Z

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

重构 TypeScript 遗留代码:从 A 到 Z



处理遗留代码是许多开发者无法回避的现实。这类项目通常是用纯 JavaScript 编写的,没有类型,依赖关系混乱,并且缺乏测试。TypeScript 提供了一套强大的工具,可以逐步改进此类代码,使其更安全、更易读、更易维护。在本文中,我们将从分析旧代码到创建清晰的类型化架构,逐步展开。



1. 准备与策略:从何入手?



在修改代码之前,你需要创建一个“安全网”。重构的主要规则是:不要破坏正在运行的功能。从搭建环境开始。



1.1. 初始化 TypeScript 与严格模式

安装 TypeScript 并创建配置文件 tsconfig.json。初始阶段可以禁用严格检查,以免被大量错误淹没,但之后需要逐步启用这些检查。



{  "compilerOptions": {    "target": "ES2020",    "module": "commonjs",    "strict": true, // 从 false 开始,然后逐渐启用    "noImplicitAny": true,    "strictNullChecks": true,    "outDir": "./dist",    "rootDir": "./src",    "allowJs": true, // 允许混用 JS 和 TS    "checkJs": false // 暂时不检查 JS 文件  },  "include": ["src/**/*"]}


1.2. 自动化与测试

添加代码检查工具(ESLint)和格式化工具(Prettier)。如果没有测试,至少为关键部分编写集成测试。这是你防止回归的保障。



  • ESLint 配合 TypeScript 插件可以捕获逻辑错误。
  • Jest 或 Vitest 用于单元测试。
  • 设置 pre-commit hooks(Husky),确保代码在提交前经过检查。


2. 逐步迁移:从 JS 到 TS



不要试图一次性重写所有内容。使用迭代的方式。这里最好的工具是 tsconfig 中的 allowJs: true。这允许你从 TypeScript 中引用 JavaScript 文件。



2.1. 重命名文件与基础类型注解

从重命名最简单的文件开始,比如将 utils.js 或 helpers.js 重命名为 .ts。编译器会开始报告隐式 any 的错误。你的任务是描述函数的签名。



之前 (JavaScript):

function calculateDiscount(price, percent) {  return price - (price * percent / 100);}


之后 (TypeScript):

function calculateDiscount(price: number, percent: number): number {  return price - (price * percent / 100);}


2.2. 处理 "any" 和 "unknown"

遗留代码中存在大量隐式 any。不要试图立刻完美地注解所有类型。使用 any 作为临时解决方案,但要用 TODO 标记。对于来自外部来源(API、localStorage)的数据,最好使用 unknown 并随后进行类型检查。



// 临时解决方案function processData(data: any) {  // TODO: 添加合适的类型  console.log(data.name);}

// 处理外部数据的正确方法function processUserData(data: unknown) { if (typeof data === 'object' && data !== null && 'id' in data) { const user = data as { id: number; name: string }; console.log(user.name); }}


3. 重构复杂结构



完成基础类型注解后,接下来要改进架构。遗留代码通常存在“上帝对象”和混乱的调用链问题。



3.1. 提取接口与类型

不要传递结构未知的对象,而是创建接口。这能让代码实现自文档化。



// 不好的做法function saveUser(user: any) {  // 不清楚 user 有哪些字段}

// 好的做法

博客

书籍推荐