老项目 TypeScript 重构经验总结

Cold 发布于 2021-07-10 12 次阅读 631 字 预计阅读时间: 3 分钟 前端开发


团队一个运行了三年的管理后台(React + JS)要持续迭代,新人对着满天飞的 undefined 一脸懵逼,我们决定渐进式迁移到 TypeScript。花了两个月,踩了不少坑,总结在这里。

渐进式迁移是唯一的路

allowJs 开着,新文件一律 ts/tsx,旧文件谁改动谁顺手迁。千万不要试图停下业务"集中迁移一个月"——业务等不起,而且集中迁移时没有上下文,只会把 any 糊得到处都是,等于白迁。

strict 要分步开

一步到位开全量 strict,编译错误上千条,团队会直接放弃治疗。我们的节奏:

  • 第一阶段:noImplicitAny 关闭,先让 ts 文件能跑
  • 第二阶段:开 strictNullChecks——这一步错误最多,但收益也最大。接口返回结构不明确的,趁机把后端文档对了一遍
  • 第三阶段:全量 strict + eslint @typescript-eslint 规则,配 CI 卡住新增代码

几个实战心得

类型从 API 边界写起。接口请求函数是数据进来的入口,把返回类型定义好,类型就顺着组件调用链自动流转下去了,大部分组件代码不用动就有类型。反过来从叶子组件开始标类型,事倍功半。

unknown 是 any 的文明替代。旧代码里 a.b.c.d 一把梭的地方,统一改成先收成 unknown,再用类型守卫一层层收窄。type guard 写起来啰嗦,但每个都是文档。

泛型别炫技。除了请求封装和少数公共 hooks,业务代码里几乎用不到复杂泛型。看到把类型体操写进业务代码的 PR 一律打回,维护的人看不懂等于负债。

any 的残留要有出口。完全禁绝不现实,约定:任何 as any 必须带注释说明原因,CI 里统计 any 数量只减不增。曲线往下走,方向就对了。

值不值

迁完后最直观的变化:运行时报错大幅减少,以前那种"改了 A 处 B 处炸"的连锁 bug 基本消失;重构的时候编译器就是安全网。新人上手时间从两周缩到一周内。要说不便的地方,就是写起来确实慢一点、构建配置复杂了一点。但对长期维护的项目,这笔账怎么算都划算。

和喜欢的一切在一起~
最后更新于 2021-07-10