vuex 4.x TS增强无限层级名称智能提示

以前用react作项目时,TS集成很到位,无不觉得高级!现在vue2项目正好需要升级,于是趁机将框架升至Vue3.0,全面集成ts,可无奈还是有很多地方不尽如人意,特别是连官方维护vuex都没有完善的ts支持,真是有些失望,早几年用redux时,dispatch方法中type、payload都是有智能提示补全的啊。
于是花了好几天时间,自己动手来完善,代码写了好几版,最终找到简单快捷的方式实现,并且是一步到位,无需任何改造。
代码已上传至github, 有兴趣的朋友可以一起学习。

github: https://github.com/nicefan/vuex-ts-enhanced
如果认为好用,也可以去支持下我在官方仓库提交的PR
Vuex PR 支持: https://github.com/vuejs/vuex/pull/2054

vuex-ts-enhanced

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

使用效果

vuex 4.x TS增强无限层级名称智能提示

安装

$ 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使用方法。

不支持的操作:

  1. 不支持对象方式分法或提交,因为没有限制载荷必须为对象类型;
  2. 不支持在带命名空间的模块注册全局 action,不推荐这种用法;
  3. 不支持动态注册的模块, 需要使用 (store.dispatch as any)('doSomething') 的方式来跳过检查;

不兼容的使用方法 createStore<State>({...})

无需手动指定<State>,默认将会自动从 state 选项中推断;当需要自定义类型时,请使用 class 进行定义并设置初始值,然后在state配置项中创建一个实例;

class State {
  name = ''
  count = 1
  list?:string[] = []
}
const store = createStore({
  state: new State(),
  ...
}

全局类型补充

将 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]
}