Autocomplete for vuex store by typescript

Ken Cheung
3 min readSep 28, 2018

--

Autocomplete by vetur

When building large scale vue project with typescript, webpack configuration maybe a nightmare for you. In this article I will suggest a little trick to provide autocomplete on vuex store actions and getters. You can also view the Github code first (It can also be used as a boilerplate).

Starting from the beginning, you need to know about vue-class-componentA class style of vue component and vue-property-decoratorhelper for using vue-class-component

Here is a simple example using class style component:

import Vue from 'vue'
import { Component } from 'vue-property-decorator'
@Component({name: 'view-helloworld'})
export default class Helloworld extends Vue {
}

For building a large-scaled app, we always use vuex in our project. There are 3 approach to use Vuex in your project.

Here comes the first approach — using mapActions and mapGetters from vuex in @component object (The same approach in using javascript development)

import { mapActions } from 'vuex'@Component({
name: 'view-helloworld',
methods: {
...mapActions({
increment: 'increment',
})
}
})
export default class Helloworld extends Vue {
}

However, in this approach is no auto-complete support in IDE.

this.increment is not found in our component

Another approach is using vuex-classBinding helpers for Vuex and vue-class-component.

import { Action } from 'vuex-class'@Component({
name: 'view-helloworld'
})
export default class Helloworld extends Vue {
@Action("increment")
public localIncrement: void
}

Vuex-class provides decorators for mapping vuex actions(also getter, mutation, state). You may have to declare interfaces in order to make the auto-complete works. But what if the increment is not returning void anymore or the name is changed? We need to modify the type and the name in our component manually. It’s not efficient.

this.Increment can be autocomplete

The last approach is using dispatch function from $store

import { Action } from 'vuex-class'@Component({
name: 'view-helloworld'
})
export default class Helloworld extends Vue {
public increment() {
this.$store.dispatch('increment')
}
}

It has the same issues as in approach #2, because we need to pass a string into dispatch function. We don’t know the return type nor the existence of the increment action from store.

So if there is an approach, which the store actions can be auto-completed, and when the action name or return type is changed we will have a notification by the compiler. Will you use it or not?

I made a store helper mixin for mapping store action and getters to the component state. As the type of existing attribute ($store._actions or $store.getters) can’t be changed by local side, I move it to another attribute i.e. myActions and myGetters

It works but still need to do some extra works (to declare our store helper typings) to have auto-complete.

It tells the typescript compiler that this.$store.myActions is MyActions and this.$store.myGetters is MyGetters.

For now on, MyAction is empty right now. We need to merge our own action inside the MyAction interface

We don’t care the first argument in action and getter so we need to remove the first argument in our interface by using ActionHelper and GetterHelper. You may take a look on type inference.

As vuex will not accept a class object, we need to convert back class to a simple object.

That’s it. If you installed vetur on your vs-code, you will get the intellisense by this.$store.myActions and this.$store.myGetters.

--

--