带有 Typescript 的 Vuex 存储类型

Posted

技术标签:

【中文标题】带有 Typescript 的 Vuex 存储类型【英文标题】:Vuex store type with Typescript 【发布时间】:2019-04-07 23:03:54 【问题描述】:

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

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

【问题讨论】:

【参考方案1】:

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

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;
,

【讨论】:

你知道是否有办法让输入与 this.$store.getters 一起工作? @maembe 不幸的是,我不这么认为——你可能会真正喜欢枚举和一些泛型,但这感觉比手动投射更糟糕。 =\【参考方案2】:

不幸的是,不可能用更具体的类型覆盖由 VueX 类型定义的 Store&lt;any&gt; 类型。我能想到的最好方法是添加第二个字段,该字段返回 $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,
);

【讨论】:

【参考方案3】:

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

$store!: Store<StoreStateType>;

我使用的另一种方法是使用MapState 或MapGetters 组件助手。他们为您创建属性,以便您可以在模板中使用它们。示例:

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

不要忘记导入 Store、您的 vuex 状态类和您使用的任何帮助器 import Store, mapState from "vuex";

【讨论】:

【参考方案4】:

没有一个答案让我满意。我做了一些挖掘,发现了这个小宝石。在我的store.ts 文件中,我只是添加:

declare module "@vue/runtime-core" 
  interface ComponentCustomProperties 
    $store: Store<State>;
  

所以看起来更像这样:

//store.ts
import  createStore, Store  from "vuex";
import  CustomTool, CustomListType  from "custom";

export type State = 
  tool: CustomTool
  list: CustomListType | null
;

export default createStore(
  state: 
    tool: CustomTool.Empty
    list: null,
   as State,
  mutations: ,
  actions: ,
  modules: 
;

declare module "@vue/runtime-core" 
  interface ComponentCustomProperties 
    $store: Store<State>;
  

使用 vue3 和 typescript 4.4。

【讨论】:

以上是关于带有 Typescript 的 Vuex 存储类型的主要内容,如果未能解决你的问题,请参考以下文章

使用带有打字稿的 Vuex 4,类型“ComponentPublicInstance”上不存在属性“$store”

在 router.ts 中访问 Vuex 存储模块的状态

问:使用 Vue 3 和 typescript(使用 cli 构建的项目)使 vuex 存储在全球范围内可用 +已解决

graphql 查询的 typescript 类型声明错误

vuex 懒加载数据

心无旁骛vuex-typescript-example