Vuex Module Decorator: How to access store within a module

1k Views Asked by At

I have been experimenting with vuex module decorator to keep good typescript in my vuex stores. But im having difficulties trying to access the store without getting type definition issues.

I am using:

  • nuxt with 'nuxt-typescript' and 'vue2-composition-api',
  • vuex with 'vuex-module-decorator' setup with getModule for SSR,

Here is a basic example of what im attempting:

store/index.ts

import { Store } from 'vuex'
import { getModule } from 'vuex-module-decorators'
import User from './user'
import Basket from './basket'

export function useUserModule(store: Store<any>): UserModule {
    return getModule(UserModule, store)
}

export function useBasketModule(store: Store<any>): BasketModule {
    return getModule(BasketModule, store)
}

store/user.ts

import { Module, VuexModule, Action } from 'vuex-module-decorators'

@Module({
    name: 'user',
    namespaced: true,
    stateFactory: true,
    preserveState: true,
})
export default class UserModule extends VuexModule {
    user: IUser | null = null

@Action
    async doSomthingWithUser(request: object) {
      console.log('success!, called from basket module')
    }
}

store/basket.ts

import { Module, VuexModule, Action } from 'vuex-module-decorators'
import { useUserModule } from '.'

@Module({
    name: 'basket',
    namespaced: true,
    stateFactory: true,
    preserveState: true,
})
export default class BasketModule extends VuexModule {
    basket: IBasket | null = null

@Action
    async doUserAction(request: object) {
      
      const userStore = useUserModule(this.store)
      //Property 'store' does not exist on type 'BasketModule'

      userStore.doSomthingWithUser({stuff:true})
    }
}

Property 'store' does not exist on type 'BasketModule'

The problem is this.store DOES exist when I console log this! The examples I found here use the this.$store which doesnt exist for me. eg: getModule(MobuleB, this.$store)

I have also tried using the traditional approach to nuxt SSR described in the docs decorators with ServerSideRender...but exactly same situation.

Everything works fine...but IDE is giving error, im new to typescript and I think the module doesnt have the type definition for store. Anyone know how I can assign a definition for this.store for ALL modules, or perhaps use the global this.$store everyone else has access to?

1

There are 1 best solutions below

0
On

Its not ideal but you can just copy the .d.ts into your own shim file and add the store reference to the class. At the root of your project add a file called 'shims-vuex-module-decorator.ts with the below content

import {
  ActionTree,
  GetterTree,
  Module as Mod,
  ModuleTree,
  MutationTree,
  Store,
  ActionContext,
} from 'vuex'
declare module 'vuex-module-decorators' {
  export class VuexModule<S = ThisType<any>, R = any> implements Mod<S, R> {
    static namespaced?: boolean
    static state?: any | (() => any)
    static getters?: GetterTree<any, any>
    static actions?: ActionTree<any, any>
    static mutations?: MutationTree<any>
    static modules?: ModuleTree<any>
    modules?: ModuleTree<any>
    namespaced?: boolean
    getters?: GetterTree<S, R>
    state?: S | (() => S)
    mutations?: MutationTree<S>
    actions?: ActionTree<S, R>
    context: ActionContext<S, R>
    store?: Store<any>
    constructor(module: Mod<S, any>)
  }
  export type ConstructorOf<C> = {
    new (...args: any[]): C
  }

  export function getModule<M extends VuexModule>(
    moduleClass: ConstructorOf<M>,
    store?: Store<any>
  ): M
}