typescript - Vuex模块中的Typescript错误“当作为表达式调用时无法解析类装饰器的签名”
问题描述
我使用从库中导出的 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: true
和name :auth
属性。从我读过的内容来看,我应该可以使用这样的@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 模块?
解决方案
错误是因为你@Action
用它不理解的参数调用 s 。文档在这里。
可能使用中最令人困惑的部分vuex-module-operators
是,与普通 Vuex 不同,@Action
跳过了 s 的第一个参数(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;
作为旁注,我不完全理解您为什么要发送setUserRoles
-state.roles
就像它state
在操作中一样可用,因此无需将角色作为参数发送。
你的意思是?setUserRoles
setUser
dispatch('setUserRoles', user.roles);
推荐阅读
- php - 使用查询 + have_posts() 循环浏览 Wordpress 帖子仅返回其中的一小部分
- wpf - WPF 根据 ComboBox 选择更改 ListView 内容
- javascript - 使用Django,Ajax,jQuery提交表单而不刷新页面?
- r - R中是否有任何类似字典的结构
- haskell - 如何在 Haskell 中制作列表地图?
- kubernetes - 身份验证问题:GitLab CI/CD 作业在运行“kubectl apply -f deployment.yaml”时失败
- python-3.x - '不允许无效请求 URL 查询参数' Django-oauth2 500 错误
- python - MongoDB 更改流使用 getMore 导致 COLLSCAN
- ssl-certificate - 在 Windows 中生成自签名证书
- python - 将模块传递给python中的变量