给vuex补充ts支持,实现无限层级名称智能提示

·  阅读 469

前言

之前用react作项目时,TS集成很到位,无不觉得高级!现在vue2项目正好需要升级,于是趁机将框架升至Vue3.0,全面集成ts,可无奈还是有很多地方不尽如人意,特别是连官方维护vuex都没有完善的ts支持,真是有些失望,早几年用redux时,dispatch方法中type、payload都是有智能提示补全的啊。

于是花了好几天时间,自己动手来完善,代码写了好几版,最终找到简单快捷的方式实现,并且是一步到位,无需任何改造。

代码已上传至github, 有兴趣的朋友可以一起学习。
github: github.com/nicefan/vue…

简介

  • 增强 stategetters 无限层级属性提示,并支持只读校验;
  • 增强 commitdispatch 方法感知所有操作类型名称并对载荷参数检查;
  • 支持模块 namespaced 属性配置,对名称进行拼接。

使用效果

image

安装

$ yarn add vuex-ts-enhanced
复制代码

使用

import { createStore} from 'vuex'
import { ExCreateStore } from 'vuex-ts-enhanced'

class State {
  count: number = 1
}

export const store = (createStore as ExCreateStore)({
  state: new State()
  ...
})
复制代码

或者使用覆盖声明方式, 在你的项目文件夹中添加一个d.ts文件:

// vuex.d.ts
declare module 'vuex' {
  export * from 'vuex/types'
  export { createStore } from 'vuex-ts-enhanced'
}
复制代码

这样就可以不改动任何原有的Vuex使用方法。

全局类型补充

将 store 安装到 Vue 应用时,会挂载this.$store属性,同时将 store 注入为应用级依赖,在未指定 InjectionKey 时将使用 "store" 作为默认 key, 因此我们可以在组合式 API 中使用inject('store')来拿到 store 实例,但是却无法感知返回的数据类型,为此我们可以使用下面的方式给 store 进行类型补充:

import { store } from '.. /src/store'

interface InjectionMap {
  'store': typeof store
}

declare module '@vue/runtime-core' {

  interface ComponentCustomProperties {
    $store: InjectionMap['store']
  }
  export function inject<S extends keyof InjectionMap>(key:S):InjectionMap[S]
}
复制代码

注意事项

  • 未支持的功能

    • 不支持对象方式分法或提交,因为没有限制载荷必须为对象类型;
    • 不支持在带命名空间的模块注册全局 action,不推荐这种用法;
    • 不支持动态注册的模块, 可以使用 (store.dispatch as any)('doSomething') 的方式来跳过检查;
  • 不兼容官方文档中的 createStore<State>({...})
    无需手动指定<State>,默认将会自动从 state 选项中推断;当需要自定义类型时,请使用 class 进行定义并设置初始值,然后在state配置项中创建一个实例;

    class State {
      name = ''
      count = 1
      list?:string[] = []
    }
    const store = createStore({
      state: new State(),
      ...
    }
    复制代码
分类:
前端
标签:
分类:
前端
标签:
收藏成功!
已添加到「」, 点击更改