带Typescript的Vuex商店类型

时间:2018-11-04 10:45:25

标签: typescript vue.js vuex

我正在尝试让Vuex商店对Typescript友好。我正在按照here的说明建立商店。但是,当我从组件访问this.$store时,类型为Store<any>

我不知道如何更改它,以使其默认为Store<MyState>而无需每次都强制转换。

3 个答案:

答案 0 :(得分:4)

如果有人遇到此问题-我们通过重新定义构造函数返回的类型来解决此问题-

import Vue, { VueConstructor } from 'vue'
import { Store } from 'vuex'
import { RootState } from '@/store/types'

abstract class VueStrongClass extends Vue {
    public $store!: Store<RootState>
}
const VueStrong = Vue as VueConstructor<VueStrongClass>;

export default VueStrong;

然后我们就

export default VueStrong.extend({
    name: 'name',

    components: {
        componentA,
        componentB,
},

这使我们能够正确使用键入:

methods: {
sessionStarted(): Boolean | undefined {
    return this.$store.state.sessionState?.session.started;
},

答案 1 :(得分:1)

您可以在组件中声明一个属性,以便打字稿将应用打字。我一直在$refs中使用它,但它也适用于$store。除了用!标记之外,您不需要对属性做任何事情。操作员告诉编译器vue将为您设置变量。

$store!: Store<StoreStateType>;

我使用的另一种替代方法是使用MapStateMapGetters组件助手。它们为您创建属性,因此您可以在模板中使用它们。示例:

@Component({
  computed: mapState({
    userFullName: (state: any) => state.user.fullName,
    userEmail: (state: any) => state.user.email
  })
})

请不要忘记导入应用商店,vuex状态类以及您使用的import { Store, mapState } from "vuex";任何帮助程序。

答案 2 :(得分:1)

不幸的是,无法用更具体的类型覆盖由VueX类型定义的Store<any>类型。我能想到的最好的办法是添加第二个返回$store但输入正确的字段,这样您就不必在所有地方使用强制类型转换或在所有组件中声明它:

import { Store } from "vuex";

// Type the $tstore properly, which is the same as $store but properly typed.
// Unfortunately you cannot override the Store<any> type.
declare module "vue/types/vue" {
  interface Vue {
    $tstore: Store<State>;
  }
}

// Set $tstore to be a getter that simply returns $store.
Object.defineProperty(Vue.prototype, "$tstore", {
  get: function() {
    return this.$store as Store<State>;
  },
  enumerable: true,
});