Search code examples
typescriptvuexvuex-modules

How to access other Vuex modules with typescript?


I'm trying to write a Vuex store with typescript (not using vuex-module-decorators, just plain Vuex + typescript to keep things simple). My root store has no state, just modules:

export interface RootState { }
export const store: StoreOptions<RootState> = {
  strict: (process.env.NODE_ENV !== 'production'),
  state: {},
  mutations: {},
  modules: {
    moduleA,
    moduleB
  }
}

moduleA has some state:

export interface ModAState { 
 aValue: string
}
const modAState: ModAState = {
 aValue: 'value A'
}
export default const moduleA = {
  namespaced: true,
  state: modAState,
  getters: {},
  mutations: {},
  actions: {}
}

as does moduleB:

export interface ModBState { 
 bValue: string
}
const modBState: ModBState = {
 bValue: 'value B'
}
const modBActions: ActionTree<ModBState, RootState> = {
  act1({state, rootState, commit, dispatch}) {
    let foo = rootState.moduleA.aValue // <<<<< Typescript error: property moduleA does not exist on '{}' 
  }
}
export default const moduleB = {
  namespaced: true,
  state: modBState,
  getters: {},
  mutations: {},
  actions: modBActions
}

The error is above in modB's act1 -- rootState is just {}, as far as typescript is concerned it has no access to the root store's modules. So how can I get moduleA's state in an action in moduleB?

Here's a codesandbox: https://codesandbox.io/embed/vuex-typescript-modules-x7f7s (the store is in App.vue there)


Solution

  • to typescript your rootState is an empty object

    // define the interface
    
    /**
     * 
     */
    export interface RootState {
      ModAState: ModAState;
      ModBState : ModBState ;
    }
    

    about the action (without changes)

    const modBActions: ActionTree<ModBState, RootState> = {
    // ...
    

    about the action (functions)

    const modBActions = {
      act1({state, rootState, commit, dispatch}: ActionContext<ModBState, RootState>): Promise<any> {
        let foo = rootState.moduleA.aValue 
      },
    }
    
    // ...
    
    

    If your rootState is undergoing many changes, you can skip this for a moment (not recommended)

    const modBActions: ActionTree<ModBState, any> = {
    // ...