返回

Vue3+Vuex+TypeScript 踩坑之旅:过河先湿鞋

前端

序言

当 Vue3 的曙光初现,Vuex 的新版本还在 Beta 测试中时,我怀着激动和忐忑的心,迫不及待地想要在项目中一试身手。然而,这份期待很快被接二连三的踩坑之旅所浇灭,让我差点把电脑砸了。

初战:any 的困扰

在使用 Vue3 时,我欣喜地发现它对 Typescript 的支持有了很大提升。然而,当我尝试在组件中使用 Vuex 的 mapState 时,却遇到了一个意想 Tribun外的障碍——any 类型。

import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState(['count']),
  },
};

当编译器提示我 count 可能是 any 类型时,我一脸茫然。这让我陷入了深深的困惑:Vuex 的状态明明是强类型化的,怎么在组件中就变成了 any

一番搜索后,我找到了答案:原来,mapState 返回的是一个函数,它接受一个字符串参数(状态名称),并返回该状态的响应式版本。然而,在 Typescript 中,这个函数的返回值类型被推断为 any,因为编译器无法确定状态的实际类型。

为了解决这个恼人的问题,我不得不在 mapState 函数中显式指定状态类型:

import { mapState } from 'vuex';

export default {
  computed: {
    ...mapState<typeof store.state>(['count']),
  },
};

再战:script 标签的无奈

怀着对 any 类型的怨念,我继续深入踩坑之旅。这次,我遇到了一个让我头疼不已的难题——script 标签。

在我的组件中,我需要使用一个第三方库,该库的引入方式是通过一个 script 标签:

<script src="path/to/library.js"></script>

然而,当我尝试编译代码时,却收到了一个意想传统的报错:Cannot find module 'path/to/library.js' or its corresponding type declarations.

一番排查后,我发现 Typescript 无法识别 script 标签中引入的库,导致它无法进行类型检查。为了解决这个讨厌的问题,我不得不手动安装该库的 Typescript 类型声明文件,并在 tsconfig.json 文件中引入它:

{
  "compilerOptions": {
    "types": ["path/to/library.d.ts"]
  }
}

终章:tsconfig.json 的救赎

在经历了 any 和 script 标签的双重打击后,我终于迎来了转机。当我对 tsconfig.json 文件进行细致的检查时,我发现了另一个潜在的问题——noUnchecked()" 选项。

{
  "compilerOptions": {
    "noUnchecked='$': true"
  }
}

这个选项会禁止 Typescript 将所有未声明的变量视为 any 类型。这意味着,在我之前的代码中,count 的类型虽然被推断为 any,但实际上它应该是 number 类型。

启用 noUnchecked='$' 选项后,编译器果然报出了正确的类型错误:count 应该是一个数字,而我却把它当成了字符串。至此,我终于拨云见日,豁然开朗。

结语

回首这段 Vue3+Vuex+Typescript 的踩坑之旅,我感到一丝欣慰,也有一丝无奈。欣慰的是,我最终解决了这些难题,为项目的发展扫清了障碍。无奈的是,这些问题本不该出现,它们本可以被更好的文档和更友好的开发体验所避免。

然而,每一次踩坑都是一次成长的契机。通过这些曲折的经历,我不仅加深了对 Vue3、Vuex 和 Typescript 的理解,也领悟到了在软件开发中细心求索、不断学习的重要性。

我将继续探索 Vue3 和 Typescript 的世界,并分享我的经验和教训,希望能够帮助更多开发者避免类似的踩坑之旅。