【问题标题】:Typescript error "Unable to resolve signature of class decorator when called as an expression" in Vuex moduleVuex模块中的Typescript错误“当作为表达式调用时无法解析类装饰器的签名”
【发布时间】:2020-09-07 14:06:14
【问题描述】:

我使用从库中导出的 Typescript 有以下 Vuex 模块:

import * as types from '@/store/types';
import {Formio} from 'formiojs';
import { VuexModule, Module, Mutation, Action } from 'vuex-module-decorators'

interface RoleItem {
  _id: string;
  title: String;
  admin: Boolean;
  default: Boolean;
}

interface RoleList {
  [key: string]: RoleItem;
}

export class Auth extends VuexModule {
  public user: {}
  public loggedIn: boolean
  public roles: {}
  public forms: {}
  public userRoles: {}

  @Action
  setUser({ state, commit, dispatch }, user) {
    commit(types.SET_USER, user);
    dispatch('setLoggedIn', true);
    dispatch('setUserRoles', state.roles);
  }
  @Action
  setLoggedIn({commit}, loggedIn) {
    commit(types.SET_LOGGED_IN, loggedIn);
  }
  @Action
  getAccess({ commit, dispatch, getters }) {
    const projectUrl = Formio.getProjectUrl();
    Formio.request(projectUrl + '/access')
      .then(function(accessItems) {
        commit(types.SET_ROLES, accessItems.roles);
        commit(types.SET_FORMS, accessItems.forms);
        if (getters.getLoggedIn) {
          dispatch('setUserRoles', accessItems.roles);
        }
    });
  }
  @Action
  setUserRoles({ commit, getters }, roles: RoleList) {
    const roleEntries = Object.entries(roles);
    const userRoles = getters.getUser.roles;
    const newRolesObj = {};
    roleEntries.forEach((role) => {
      const roleData = role[1];
      const key = 'is' + role[1].title.replace(/\s/g, '');
      newRolesObj[key] = !!userRoles.some(ur => roleData._id === ur);
    });
    commit(types.SET_USER_ROLES, newRolesObj);
  }

  @Mutation
  [types.SET_USER](user) {
    this.user = user;
  }
  @Mutation
  [types.SET_LOGGED_IN](loggedIn: boolean) {
    this.loggedIn = loggedIn;
  }
  @Mutation
  [types.SET_ROLES](roles: RoleList) {
    this.roles = roles;
  }
  @Mutation
  [types.SET_FORMS](forms) {
    this.forms = forms;
  }
  @Mutation
  [types.SET_USER_ROLES](userRoles) {
    this.userRoles = userRoles;
  }
}

export default Auth;

我想简单地将它作为命名空间的 Vuex 模块导入到父 vue 应用程序中,并将其作为新模块添加到我的商店:

import Vue from 'vue';
import Vuex from 'vuex';
import { Auth } from 'vue-formio'

Vue.use(Vuex);

...

resourceModules.auth = Auth;

export default new Vuex.Store({
  modules: resourceModules,
  strict: debug,
});

那部分一切正常。问题是在导出的存储中设置namespaced: truename :auth 属性。根据我的read,我应该可以像这样使用@Module 装饰器来做到这一点:

@Module({ namespaced: true, name: 'auth' })
export class Auth extends VuexModule {

但是,一旦我在 @Module 装饰器后添加括号,我的 IDE 中就会出现此 TS 错误:

TS1238:当作为表达式调用时,无法解析类装饰器的签名。无法调用其类型缺少调用签名的表达式。类型“void”没有兼容的调用签名。

vuex-module-decorators 代码中所示,这些是允许的选项:

export interface StaticModuleOptions {
  /**
   * name of module, if being namespaced
   */
  name?: string;
  /**
   * whether or not the module is namespaced
   */
  namespaced?: boolean;
  /**
   * Whether to generate a plain state object, or a state factory for the module
   */
  stateFactory?: boolean;
}

这是我第一次涉足 Typescript,所以我很难过。我还在研究,但与此同时,如何使用 Typescript 将命名空间添加到这个 Vuex 模块?

【问题讨论】:

    标签: typescript vue.js module vuex


    【解决方案1】:

    我想出一个快速修复是添加

    从 'vuex-module-decorators/dist/types/moduleoptions' 导入 { ModuleOptions };

    @模块({ 动态:真实, 名称:'用户', 命名空间:真, 店铺:店铺 } 作为模块选项)

    到配置对象。

    【讨论】:

      【解决方案2】:

      错误是因为您使用它不理解的参数调用@Actions。文档here.

      使用vuex-module-operators 可能最令人困惑的部分是,与普通的Vuex 不同,@Actions 的第一个参数(ActionContext)被跳过了。它的地址为this.context

      以下是您的一项操作将如何使用此包:

      @/store/auth.ts

      import { ActionContext } from 'vuex';
      import { Module, VuexModule, Action } from 'vuex-module-decorators';
      import * as types from './types';
      import store from '.';
      
      @Module({ namespaced: true, store, name: 'auth' })
      export default class AuthStore extends VuexModule {
      
        @Action
        async setUser(user) {
          const { state, commit, dispatch } = this.context;
          commit(types.SET_USER, user);
          dispatch('setLoggedIn', true);
          dispatch('setUserRoles', state.roles); // could be `this.roles`
        }
      }
      

      确保在创建商店后,您还在主商店文件中调用 getModule(Auth, store)。我相信这个调用除了推断类型没有其他效果。 (没有它,商店似乎可以正常工作,但 Typescript 不再有效)。示例:

      @/store/index.ts

      import Vue from 'vue';
      import Vuex from 'vuex';
      import Auth from './auth';
      import { getModule } from 'vuex-module-decorators';
      
      Vue.use(Vuex);
      
      const store = new Vuex.Store({
        //...
        modules: {
          auth: Auth
        }
      });
      
      getModule(Auth, store);
      
      export default store;
      

      作为旁注,我不完全理解您为什么要发送 setUserRolesstate.roles - statesetUserRoles 操作中可用,就像它在 setUser 操作中可用一样,所以不需要将角色作为参数发送。
      你是说dispatch('setUserRoles', user.roles);吗?

      【讨论】:

        猜你喜欢
        • 2018-12-03
        • 2016-07-26
        • 2020-01-30
        • 1970-01-01
        • 2016-10-08
        • 2019-04-18
        • 2016-04-02
        • 2021-07-06
        • 1970-01-01
        相关资源
        最近更新 更多