Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Intellisense for Vuex Store in VS Code

I am building an application using vuejs2, vuex, and typescript in visual-studio-code. I have the vetur extension installed. I have built a definition file to give me intellisense for most of my project, but I haven't been able to figure out how to add my vuex store to intellisense. I've read through the Definition Documentation, but I haven't been able to puzzle together how I might do this. My goal is to be able to get intellisense on anything in this.$store.. Currently, vetur provides intellisense for state, getters, etc. but it does not provide intellisense for the next level (e.g. this.$store.state.TestVariable). How can I get intellisense for my vuex store?

Contract Management Store

import Vue from 'vue';
import Vuex from 'vuex';

Vue.use(Vuex);

export default new Vuex.Store({
    state: {
        Contract: new Library.Model.Entity.Contract()
    }
});

Contract Component

<template>
    <contract-line></contract-line>
</template>

<script lang="ts">
    import Vue from 'vue';
    import Vuex from 'vuex';
    import store from '../store/ContractManagementStore';
    import ContractLine from "./ContractLine.vue";

    export default Vue.extend({
        name: 'contract-management',
        store,
        components: {
            'contract-line': ContractLine
        }
    });
</script>

<style>

</style>

Contract Line Component

<template>
    <button v-if="CanDelete"></button>
</template>

<script lang="ts">
    import Vue from 'vue';
    import Vuex from 'vuex';

    Vue.use(Vuex);

    export default Vue.extend({
        computed:{
            CanDelete(): Boolean {
                // Looking for intellisense after this.$store.state.
                return this.$store.state.Contract.ContractStatus.Value === Library.Enums.ContractStatus.Draft
            }
        }
    });
</script>

<style>

</style>
like image 492
Tim Hutchison Avatar asked Jun 01 '18 12:06

Tim Hutchison


1 Answers

You could achieve this by explicitly typing your state.

In Contract Management Store.ts

export interface ContractManagementState {
    Contract: ContractType;
}

In your Component:

...
(this.$store as Store<ContractManagementState>).<intellisense here>

You have to do this every time you access the state this way, unfortunately. This is due to the way Vuex uses module augmentation in order to declare the existence of the $store property to typescript.

In vuex/types/vue.d.ts:

declare module "vue/types/vue" {
  interface Vue {
    $store: Store<any>;
  }
}

You cannot override the any with your concrete state typings (this is called module augmentation after all). A possible solution is to use getters for accessing your Store. Several typescript libraries exist for adding type information to getters, mutators, and actions, such as vuex-typescript and vuex-typex.

like image 153
Georg Grab Avatar answered Nov 14 '22 02:11

Georg Grab