Using the Vuex Module Decorator: A guide on accessing the store from a module

Recently, I've been playing around with the vuex module decorator in order to maintain good TypeScript practices in my vuex stores. However, I'm facing issues when trying to access the store without encountering type definition problems.

My setup includes:

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

Below is a basic example of what I am trying to achieve:

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 issue here is that this.store does exist when I log this! The references I came across here use this.$store which seems to be missing in my case. For example: getModule(MobuleB, this.$store)

I have also attempted the conventional SSR approach in Nuxt as mentioned in the documentation decorators with ServerSideRender... but I'm facing the same situation.

Although everything seems to be working fine, my IDE is flagging an error. I am new to TypeScript and I suspect the module lacks the type definition for the store. Does anyone have a solution for assigning a definition to this.store for ALL modules, or perhaps utilizing the global this.$store that others seem to have access to?

Answer №1

If you're in a pinch, you can simply duplicate the .d.ts file into your own shim document and include the store reference in the class. To do this, create a file named 'shims-vuex-module-decorator.ts' at the root of your project with the provided code snippet:

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
}

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

The type 'undefined' cannot be assigned to a different type within the map() function, resulting in a loss of type information

I am facing an issue in my redux toolkit where an action is trying to set some state. Below is the relevant code snippet: interfaces export interface ProposalTag { id: number; name: string; hex: string; color: string; } export interface ProposalS ...

Using ES6, one can filter an array of objects based on another array of values

Seeking assistance with creating a function to filter an array of objects using another array as reference values. For example: The array containing objects: const persons = [ { personId: 1, name: 'Patrick', lastName: 'Smit ...

Breaking down arrays in Typescript

Let's say I have an array like this: public taskListCustom: any=[ {title: 'Task 1', status: 'done'}, {title: 'Task 2', status: 'done'}, {title: 'Task 3', status: 'done'}, {title: 'Task ...

What causes the select dropdown to display an empty default in Angular 8 following an HTTP request?

I have created a simple HTML code to populate array elements in a dropdown list, with the default value being fetched from an HTTP service during the ngOnInit lifecycle hook. However, I am encountering an issue where the default value is displayed as empty ...

Potential keys + keys that are present in the `initialData`

Is there a way to specify the type of data in order to include all keys that exist in initialData plus additional keys from Item as Partial(optional)? class TrackedInstance<Item extends Record<string, any>, InitialData extends Partial<Item> ...

The error TS2304 occurs when the e2e tsconfig types cannot find the name 'browser'

I am facing challenges while setting up a sample angular project with a basic webdriverio end-to-end test, encountering some compilation errors in my e2e test. Setting up tsconfig The project is configured with the following key files: e2e / test / [e2e t ...

Issues with multiple validators in Angular 8 intricately intertwined

I'm facing an issue with a reactive form control that has multiple validators. Despite defining the validation methods, the form is not being validated as expected. Below is the code snippet illustrating my attempted solutions. Method 1: civilIdNumbe ...

Spread an all-encompassing category across a collection

What is the method in TypeScript to "spread" a generic type across a union? type Box<T> = { content: T }; type Boxes<string | number> = Box<string> | Box<number>; (Given that we are aware of when to use Boxes versus Box) ...

The type does not have a property named 'defaultProps'

I have a Typescript React class component structured like this: import React, { Component } from 'react'; interface Props { bar?: boolean; } const defaultProps: Partial<Props> = { bar: false, }; class Foo extends Component<Props& ...

Encountered an issue while trying to assign a value to the 'value' property on an 'HTMLInputElement' within a reactive form

When I upload a picture as a data record, the image is sent to a server folder and its name is stored in the database. For this editing form, I retrieve the file name from the server and need to populate <input type="file"> in Angular 6 using reacti ...

There is a WARNING occurring at line 493 in the file coreui-angular.js located in the node_modules folder. The warning states that the export 'ɵɵdefineInjectable' was not found in the '@angular/core' module

I encountered a warning message while running the ng serve command, causing the web page to display nothing. Our project utilizes the Core Ui Pro Admin Template. Here is the list of warning messages: WARNING in ./node_modules/@coreui/angular/fesm5/coreu ...

typescript scrolling location

In my Angular UI code, I have a component class that includes the following structure: app.component.html //... <div class="banner"> <p-dialog [(visible)]="displayCOI" styleClass="coiDialog" [contentStyle]=" ...

Having difficulty incorporating TypeScript into Vue

A little while ago, I set up a vue project using vue init webpack . and everything was running smoothly. Recently, I decided to incorporate typescript and ts-loader. I created a file in the src directory with the following content: declare module '* ...

Switching cell icon when clicked - A step-by-step guide

I have a situation in ag-grid where I need to update the icon of a button in a cell when it is clicked to indicate progress and then revert back to its original state upon completion of the action. Below is the code snippet: my-custom.component.ts < ...

Changing background color during drag and drop in Angular 2: A step-by-step guide

A drag and drop container has been created using Angular 2 typescript. The goal is to alter the background color of the drag & drop container while dragging a file into it. Typescript: @HostListener('dragover', ['$event']) public onDr ...

Retrieving a list of actions triggered: Redux

In my Angular project, I am utilizing Redux to manage state and handle API calls. While exploring the redux devtools, I discovered a comprehensive list of executed actions. Is there a method to access a similar list of actions triggered within my angular a ...

Encountering a TS1005 error while trying to import types from a type definition file

Within my project, one of the libraries called parse5 is providing typing information in .d.ts files. The current syntax used to import types is causing several TypeScript errors during application runtime because TypeScript does not seem to recognize this ...

Batch requesting in Typescript with web3 is an efficient way to improve

When attempting to send a batch request of transactions to my contract from web3, I encountered an issue with typing in the .request method. My contract's methods are defined as NonPayableTransactionObject<void> using Typechain, and it seems tha ...

How to convert an attribute of an object within a list to a string separated by commas in TypeScript and Angular

I am working with an array of person objects in Angular 5 and displaying them in HTML using ngFor. The Person objects also contain an array of Role objects. persons:Array<Person>=[]; Each Role object is structured like this: export class Role{ ...

How can we effectively implement alert notifications for validating image sizes and formats prior to uploading?

code playground : https://codesandbox.io/s/quizzical-lamport-ql5ep I'm encountering an issue with the code provided in the CodeSandbox link. https://i.sstatic.net/xg3aK.png I've attempted to resolve this issue using various methods, but unfortu ...