What is the best approach for implementing Vuex with TypeScript?

My research on the topic has primarily led me to this informative article.

I am currently working on setting up a store with 2 modules.

export interface RootState {
    /** root state props **/
}

const store: StoreOptions<RootState> = {
    modules: {
        foo,
        bar,
    },
};

export default new Vuex.Store<RootState>(store);

I have created two modules:

export interface FooState {
    //(...)    
}

export const foo: Module<FooState, RootState> = {
    //(...)
};

export interface BarState {
    //(...)    
}

export const bar: Module<BarState, RootState> = {
    //(...)
};

Everything was going smoothly until I encountered a situation where I needed a getter from the foo module to access the bar state:

export const getters: GetterTree<FooState, RootState> = {
    getInfo: (state, {}, rootState) => number {
        const value = rootState.bar.somevalue;
        //(...)
    },
};

However, I received a linting error stating that rootState did not have a bar property. After some consideration, I resolved the issue by modifying the original RootState interface:

export interface RootState {
    /** root state props **/
    foo: FooState;
    bar: BarState;
}

This modification fixed the problem and enhanced the IDE intellisense functionality.

Is it appropriate to add all modules into the RootState interface used by StoreOptions?

Additionally, there appears to be limited documentation available on these typed interfaces (StoreOptions, Module, GetterTree, etc): Is Vuex sufficiently developed to be utilized with typescript?

Edit: I neglected to mention that I still need to cast `this.$store` when accessing the store from a component (though this can potentially be minimized with vuex-class). There is an unanswered inquiry on this matter in a question thread. Until a solution arises, is this the only workaround available?

Answer №1

If you're looking to use Vuex with TypeScript, you can achieve perfect compatibility by utilizing specific vuex imports:

import {GetterTree, MutationTree, ActionTree} from "vuex"

The example provided below demonstrates the simplest and most comprehensive approach to integrating vuex in a TypeScript environment.

Main store file:

import Vue from 'vue'
import Vuex from 'vuex'
import { GetterTree, MutationTree, ActionTree } from "vuex"
import MySubModule from '@/store/submodule'

Vue.use(Vuex)

class State {
    userId: string | null = null;
}

const getters = <GetterTree<State, any>>{
};

const mutations = <MutationTree<State>>{
    setUserId(state, payload) {
        state.userId = payload;
    }
};

const actions = <ActionTree<State, any>>{
    fetchUserId(store) {
    }
};

export default new Vuex.Store({
    state: new State(),
    mutations: mutations,
    actions: actions,
    modules: {
        subModuleName: MySubModule,
        //other submodules
    }
})

SubModule store file:

import { GetterTree, MutationTree, ActionTree } from "vuex"

class State {
}

const mutations = <MutationTree<State>>{
};

const actions = <ActionTree<State, any>>{
};

const MySubModule = {
    namespaced: true,
    state: new State(),
    mutations: mutations,
    actions: actions
};

export default MySubModule;

This information is intended to be of assistance!

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 type 'Element or null'

One of the components I am using looks like this: const data: any[] = [] <Tiers data={data}/> This is how my component is structured: const Tiers = ({ data, }: { data?: any; }) => { console.log('data', data?.length!); ...

Issue with triggering blur event in Internet Explorer while using Angular 2+

The issue discussed in the Blur not working - Angular 2 thread is relevant here. I have a custom select shared component and I am attempting to implement a blur event to close it when the component loses focus. // HTML <div (blur)="closeDropDown()" t ...

Tips for personalizing the error message displayed on Webpack's overlay

Is there a way to personalize the error overlay output message in order to hide any references to loaders, as shown in this image: https://i.sstatic.net/ESFVc.png Any suggestions on how to remove the line similar to the one above from the overlay output? ...

Put off the assessment of JSX

As I was working with a function that returns JSX to React components, I realized the need to include some state variables of the components in the JSX as well. Each component might require changing the JSX or its values. Take a look at the code snippet be ...

The element is assumed to have an 'any' type due to the index expression not being of type 'number'. - Error in Index Signature

I've recently started using TypeScript and encountered the following issue: Element implicitly has an 'any' type because index expression is not of type 'number' This error message appears on this line --> const { status, msg ...

What is the best way to loop through a formarray and assign its values to a different array in TypeScript?

Within my form, I have a FormArray with a string parameter called "Foo". In an attempt to access it, I wrote: let formArray = this.form.get("Foo") as FormArray; let formArrayValues: {Foo: string}[]; //this data will be incorporated into the TypeScript mod ...

Users are reporting a problem with the PrimeNG confirmation dialog where it becomes unresponsive and locks up the screen

Previously functioning code seems to have been affected by an update to PrimeNG. The confirmation dialog that was once usable is now hidden behind a gray click-mask, rendering everything on the screen unclickable: https://i.sstatic.net/YN7Iu.png The HTML ...

Tips for preventing unforeseen consequences in computed properties with VueJS

Currently, I am facing a challenge prefilling a form with data from a Vuex store. The code provided seems to give the expected result, but I am aware that this might not be the correct approach. My experience with Vue/Vuex is still limited. Since the input ...

Is it possible to automatically open the Tinymce Comments sidebar without the need for a manual button click?

After successfully implementing the Tinymce comments plugin into our configuration, we have come across a request from our users. They would like the 'showcomments' button to automatically trigger on page load, displaying the sidebar containing t ...

Unable to utilize MUI Dialog within a ReactDOMServer.renderToStaticMarkup() call

I recently started using the DIALOG component for the first time, expecting it to seamlessly integrate into my setup. However, much to my disappointment, it did not work as expected. After spending a considerable amount of time troubleshooting the issue, I ...

Looking to organize an array of objects containing two string elements (countries) based on the country name using TypeScript or the Lodash library?

Below is an example of an array of objects I am working with: { countries: [{ "country_alpha2_code": "PW", "country_name": "PALAU" },{ "country_alpha2_code": "US&qu ...

Having trouble retrieving a custom canvas attribute in Vue?

Looking for assistance with implementing a Vue component using this specific component: https://www.npmjs.com/package/aframe-draw-component. I am trying to utilize Advanced Usage with the “aframe-draw-component” it seems to be compatible with raw HT ...

Authenticate users using Azure Active Directory in a Vue.js application

Exploring Vue.js and Azure for the first time. Tasked with developing a Login interface in Vue that authenticates users based on their roles in Azure. Curious about the process of connecting Vue and Azure AD. Any suggestions or ideas on how to achieve thi ...

Can a type be referenced using the generic name?

My selection includes: export type DocumentType = | Item | List | User export type DocumentInputType = | ItemInputType | ListInputType | UserInputType I want to develop a feature that can determine the input type based on the document type wi ...

The proper method for updating data on a backend API using Axios and Vue

I am working on a Vue application that includes several form fields. I want to ensure that any changes made by the user are saved in real-time to a backend database using a REST API with Axios, without requiring the user to click a save button. I have two ...

Translating a C# ViewModel into TypeScript

Here is a C# viewmodel example: public class LoginModel { [Required(ErrorMessage = "Email is not specified")] public string Email { get; set; } [Required(ErrorMessage = "No password is specified")] [DataType(DataType.Password)] public ...

Hold tight for the function to complete

Here is the structure I am working with: function1 () { A; function2(){}; B; } Is there a way to make function2 return a result before executing B? Currently it is always A->B->function2 Any insights or suggestions would be greatly appreciated. Sin ...

How can Laravel capture a GET request sent by vue.js?

Querying Data with Vue.js methods :{ fetchData(){ var requestData ={ client_id: 2, client_secret: '5YVQ6rsSehoh5BOWsxAU3KxGeqT1tCRGHn5dx1iX', grant_type: 'password& ...

Using data analysis to customize the appearance of boundaries across various map styles - Google Maps Javascript API V3

Utilizing data-driven styling for boundaries in Google Maps Javascript API V3 is a fantastic feature that appears to be compatible with all map types such as terrain, satellite, and hybrid. Nevertheless, I have encountered difficulties in making it visible ...

When HTMLElement focus is activated, it interrupts the flow of execution

(the code presented is in TypeScript and I'm working with Angular 5, but I don't think that's the issue, so prove me wrong!) I have a basic input field that triggers events in an Angular component. (EDIT: I've added the complete compo ...