Reputation: 3321
Starting from a minimal Vue2+Vuex typescript app created with @vue/cli
. I want to ensure references to this.$store.state
within a component are of the correct type declared by the Vuex store and its modules.
How can I achieve this? Without intervention, all references to this.$store
resolve to Store<any>
.
In this commit I changed the default src/store/index.ts
created by @vue/cli
to introduce a message
property in the store...
import Vue from "vue";
import Vuex from "vuex";
Vue.use(Vuex);
interface RootState {
message: string;
}
const state: RootState = {
message: "olleH",
};
export const store = new Vuex.Store({
state,
mutations: {},
actions: {},
modules: {},
});
In this commit I updated shims-vue.d.ts
to read as follows following guidance online to add global typed references to the Vue VM (I suspect the approach only applies to Vue3 though, given the URL of this documentation is next.vue...)...
import type { HelloStore } from "./store";
declare module "*.vue" {
import Vue from "vue";
export default Vue;
}
declare module "@vue/runtime-core" {
interface ComponentCustomProperties {
$store: HelloStore;
}
}
Attempting to get autocompletion support within VSCode for this.$store.state
still doesn't give me a message
property.
I can't find any guidance for how to achieve this for Vue2 anywhere.
What is the pattern I should use so that this.$store
gets the proper typing within my Vue2 components using Vuex3. It seems crazy that you can't get properly typed values with the latest stable releases of these tools. What have I missed?
The repro at https://github.com/cefn/vuex-store-typing is my reference case for anyone wanting to experiment.
Upvotes: 2
Views: 2678
Reputation: 138276
The module name you're using in your type augmentation is for Vue 3 only (the code is slightly different in Vue 2), but support for type augmentation of the $store
instance property was only added in Vuex 4. It's not possible in Vuex 3.
However, you could actually use the exported store
instance (already typed as HelloStore
) instead of this.$store
, as they're the same instance:
import store from '@/store' // store type is HelloStore
export default {
mounted() {
console.log(this.$store === store) // => true
}
}
Upvotes: 3