Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue Vuex with Typescript Vuex object not known type

I am having issues trying to get Vuex with Typescript working. I did an example without typescript which worked just fine as shown first below. I am creating a Vuex module and then adding it as shown below

src -> store -> index.js

import Vue from 'vue';
import Vuex from 'vuex';
import robotsModule from './modules/products';

Vue.use(Vuex);

export default new Vuex.Store({
  modules: {
    products: productsModule
  },
});

src -> store -> modules -> products.js

import axios from 'axios';

export default {
  namespaced: true,
  state: {
    products: [],
  },
  mutations: {
    addProduct(state, product) {
      state.products.push(product);
    },
    updateProduct(state, products) {
      state.parts = products;
    },
  },
  actions: {
    getProducts({ commit }) {
      axios
        .get('/api/products')
        .then(result => commit('updateProduct', result.data))
        .catch(console.error);
    }
  },
};

Now when I want to use typescript it keeps complaining that

"Binding element 'commit' implicitly has an 'any' type."

As you can see I have currently specified the state as any which also seems wrong. How do I make this work nicely with typescript?

src -> store -> modules -> products.ts

import axios from 'axios';
import { Product } from '@/models/product';

export default {
  namespaced: true,
  state: {
    products: new Array<Product>(),
  },
  mutations: {
    updateProducts(state: any, products: Product[]) {
      state.products = products;
    },
    addProduct(state: any, product: Product) {
      state.products.push(product);
    },
  },
  actions: {
    getProducts({ commit }) {
      axios
        .get('/api/products')
        .then(result => commit('updateProducts', result.data))
        .catch(console.error);
    },
  },
};
like image 331
Andrew Avatar asked Jul 16 '20 14:07

Andrew


1 Answers

I found an example online which showed that I needed to have the commit as a function

getProducts({ commit }: { commit: Function }) {

full file here

import axios from 'axios';

import { Product } from '@/models/product';
import State from '@/models/state';

export default {
  namespaced: true,
  state: {
    items: new Array<Product>(),
  } as State,
  mutations: {
    updateProducts(state: State, products: Product[]) {
      state.items = products;
    },
    addProduct(state: State, product: Product) {
      state.items.push(product);
    },
  },
  actions: {
    getProducts({ commit }: { commit: Function }) {
      axios
        .get('/api/products')
        .then(result => {
          commit('updateProducts', result.data);
        })
        .catch(console.error);
    },
  },
};

Also create a State class that I could then say is my state object

import Vue from 'vue';
import { Product } from '@/models/product';

export default class State extends Vue {
  items: Product[] = new Array<Product>();
}

Update 15-03-2021 - A work colleague of mine said he now used https://www.npmjs.com/package/direct-vuex which makes it easier!

like image 76
Andrew Avatar answered Oct 03 '22 04:10

Andrew