《一次 TypeScript 迁移记录》
# 背景
前段时间已经将 vue 升级为 3.x 版本(Vue2 升级到 Vue3 记录 )。虽然 vue3 天然支持 Typescript ,但原来旧代码中还有很多 js 文件,为了能有更加统一整洁的开发体验,需要将原有的 js 文件迁移为 Typescript。
# 迁移工具
本次迁移使用到的工具
- @vue/cli-plugin-typescript:vue-cli 的 Typescript 插件
- ts-migrate: Airbnb进行大规模 TypeScript 迁移的神器
# 开始迁移
# 1. 添加 ts 支持
由于原来的项目是使用 vue-cli 搭建的,所以直接执行以下指令,根据实际需求选择对应的选项即可。
本次迁移选择不把所有的 js 转为 ts。如果一次性把所有的 js 变成 ts,会让排查变得困难。
vue add typescript
此时生成了 ts 有关的配置文件。重新启动,发现项目能正常跑起来,但不是我们想要的效果,因为 js 还没迁移。
# 2. 使用 ts-migrate
# 安装
npm install ts-migrate -D
# 将指定文件夹下的 js 重命名为 ts
npx ts-migrate rename <folder>
# 修复 ts 错误
npx ts-migrate migrate <folder>
2
3
4
5
6
7
8
执行完以上命令后,可以发现 .js 文件已经变成了 .ts 后缀 ,很多地方都加上了类型推断。
但也有很多地方都出现了下面的提示:
// @ts-expect-error ts-migrate(7053) FIXME: xxx
这是 ts-migrate 识别到无法转换的语句,自动添加的提示,根据提示一个个修复即可。
# 3. 修复 ts 报错
通过步骤二将 js 转换为 ts 后,会发现项目无法启动。可以根据编辑器的提示逐步修改。建议是同类型报错一次性调整,这样便于后面查看。
TIP
VS code 使用小技巧:
- 使用正则匹配搜索:ctrl + f (或全局搜索),输入
\s*\/\/\s*@ts-expect-error.*$
,可以删除所有以// @ts-expect-error
开头的注释行。 - 替换空行。使用正则匹配搜索:
^\s*(?=\r?$)\n
,可以删除所有的空行。
# 遇到的问题
# 1. Ts 无法识别 .vue 文件
报错信息:找不到模块“XX”或其相应的类型声明
ts 无法自动识别 .vue 文件,需要给 vue 文件添加 .vue 后缀
// import AutoColumn from "@/components/AutoColumn";
// 指定后缀
import AutoColumn from "@/components/AutoColumn.vue";
2
3
# 2. 无法找到模块“xx”的声明文件
报错信息:无法找到模块“xx”的声明文件
引用的第三方报这个错误,因为无法找到声明文件,可以根据提示到 npm 上看看有没有对应的包,如果有则直接安装,没有则需要到 src/global.d.ts
添加声明,如:
// src/global.d.ts
declare module "alife-logger";
2
# 3. 全局属性报错
报错信息:类型“CreateComponentPublicInstance xxx”上不存在属性“$message”
Vue - 为 globalProperties 扩充类型
需要到 src/env.d.ts
添加声明
// src/env.d.ts
declare module "@vue/runtime-core" {
interface ComponentCustomProperties {
$message: any
// ...
}
}
2
3
4
5
6
7
8
# 4. Vue mixin.ts 无法正确识别 this
报错信息:类型“{ data(): { },mounted(): void; methods: { ...; }; }”上不存在属性“xxx”
Vue - Typescript 支持
// mixins.ts
import { defineComponent } from "vue";
export default defineComponent({
// xxx
})
2
3
4
5
WARNING
不建议再使用 mixin 的方法拆分逻辑,如果非要,记得用 defineComponent
定义一下,不要使用 (this as any)
方式。
# Typescript 学习
虽然 ts 能完全兼容 js 的写法,但还是需要多了解 ts 的一些特性,在后续开发中能使用这些新特性,发挥 ts 的作用。
# 学习文档
- Typescript 文档 英文版
- Typescript 文档 中文版(中文版仅更新到 3.1 版本,我们使用的是 4.1 版本)
- Vue - Typescript 迁移