《一次 TypeScript 迁移记录》


2022-05-19 上次更新时间:6/13/2022, 4:12:56 PM 0 javascript

# 背景

前段时间已经将 vue 升级为 3.x 版本(Vue2 升级到 Vue3 记录 )。虽然 vue3 天然支持 Typescript ,但原来旧代码中还有很多 js 文件,为了能有更加统一整洁的开发体验,需要将原有的 js 文件迁移为 Typescript。

# 迁移工具

本次迁移使用到的工具

# 开始迁移

# 1. 添加 ts 支持

由于原来的项目是使用 vue-cli 搭建的,所以直接执行以下指令,根据实际需求选择对应的选项即可。

本次迁移选择不把所有的 js 转为 ts。如果一次性把所有的 js 变成 ts,会让排查变得困难。

vue add typescript
1

此时生成了 ts 有关的配置文件。重新启动,发现项目能正常跑起来,但不是我们想要的效果,因为 js 还没迁移。

# 2. 使用 ts-migrate

# 安装
npm install ts-migrate -D

# 将指定文件夹下的 js 重命名为 ts
npx ts-migrate rename <folder> 

# 修复 ts 错误
npx ts-migrate migrate <folder>
1
2
3
4
5
6
7
8

执行完以上命令后,可以发现 .js 文件已经变成了 .ts 后缀 ,很多地方都加上了类型推断。

但也有很多地方都出现了下面的提示:

// @ts-expect-error ts-migrate(7053) FIXME: xxx
1

这是 ts-migrate 识别到无法转换的语句,自动添加的提示,根据提示一个个修复即可。

# 3. 修复 ts 报错

通过步骤二将 js 转换为 ts 后,会发现项目无法启动。可以根据编辑器的提示逐步修改。建议是同类型报错一次性调整,这样便于后面查看。

TIP

VS code 使用小技巧:

  1. 使用正则匹配搜索:ctrl + f (或全局搜索),输入 \s*\/\/\s*@ts-expect-error.*$,可以删除所有以 // @ts-expect-error 开头的注释行。
  2. 替换空行。使用正则匹配搜索:^\s*(?=\r?$)\n,可以删除所有的空行。

# 遇到的问题

# 1. Ts 无法识别 .vue 文件

报错信息:找不到模块“XX”或其相应的类型声明

ts 无法自动识别 .vue 文件,需要给 vue 文件添加 .vue 后缀

// import AutoColumn from "@/components/AutoColumn";
// 指定后缀
import AutoColumn from "@/components/AutoColumn.vue";
1
2
3

# 2. 无法找到模块“xx”的声明文件

报错信息:无法找到模块“xx”的声明文件

引用的第三方报这个错误,因为无法找到声明文件,可以根据提示到 npm 上看看有没有对应的包,如果有则直接安装,没有则需要到 src/global.d.ts 添加声明,如:

// src/global.d.ts
declare module "alife-logger";
1
2

# 3. 全局属性报错

报错信息:类型“CreateComponentPublicInstance xxx”上不存在属性“$message”

Vue - 为 globalProperties 扩充类型

需要到 src/env.d.ts 添加声明

// src/env.d.ts
declare module "@vue/runtime-core" {

    interface ComponentCustomProperties {
      $message: any
      // ...
    }
  }
1
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
})
1
2
3
4
5

WARNING

不建议再使用 mixin 的方法拆分逻辑,如果非要,记得用 defineComponent 定义一下,不要使用 (this as any) 方式。

# Typescript 学习

虽然 ts 能完全兼容 js 的写法,但还是需要多了解 ts 的一些特性,在后续开发中能使用这些新特性,发挥 ts 的作用。

# 学习文档

# 源码欣赏

上次更新时间: 6/13/2022, 4:12:56 PM