【问题标题】:`direct-vuex` getters has `{}` type with no property but it's filled at runtime`direct-vuex` getter 具有 `{}` 类型,没有属性,但它在运行时填充
【发布时间】:2020-10-15 13:10:40
【问题描述】:

我正在使用 typescript + direct-vuex 包实现我的 VueJS 商店,但在使用 getter 时遇到了问题。

store.getters 的类型是{},没有属性。但是在运行时它具有属性。 奇怪的是UserModule.getters 类型是正确的,但商店却没有:

userModule.getters:

store.getters:

存储/索引.ts:

Vue.use(Vuex);

const {
  store,
  rootActionContext,
  moduleActionContext,
  rootGetterContext,
  moduleGetterContext,
} = createDirectStore({
  state: {
    CurrentUser: {} as User,
  },
  modules: {
    user: userModule,
    chat: chatModule,
  },
});

console.log(store.getters);

store/modules/user/index.ts:

export const userModule = defineModule({
  state: {
    userList: [],
    currentUser: {},
  } as UserStates,

  actions: userActions,
  mutations: userMutations,
  getters: userGetters,
});

store/modules/user/userGetters.ts:

export const userGetters = defineGetters<UserStates>()({
  canUpdateUsers(...args): boolean {
    const { state } = userGetterContext(args);
    console.log("Getters state: ", state);

    return (
      state.currentUser.role === "admin" ||
      state.currentUser.role === "presenter"
    );
  },
});

【问题讨论】:

  • 这里有同样的问题。运气好吗?

标签: typescript vue.js vuex


【解决方案1】:

经过多次反复试验,我得出以下结论:

// store/index.ts
...

// Declare the intersection type of all modules' getters
// This works, because all of the getters are at root at runtime,
// proved by printing the value of `this.$store.direct.getters` from any component
type RootGetters = typeof AccountUserStore.getters &
  typeof CurrentUserStore.getters &
  typeof MessagesStore.getters &
  typeof PermissionStore.getters &
  typeof UserInterfaceStateStore.getters;

// We need to know the type of the store's state as well, so type out that structure too
type RootState = {
  accounts: typeof AccountStore.state;
  accountUsers: typeof AccountUserStore.state;
  currentUser: typeof CurrentUserStore.state;
  documents: typeof DocumentStore.state;
  messages: typeof MessagesStore.state;
  permissions: typeof PermissionStore.state;
  ui: typeof UserInterfaceStateStore.state;
  users: typeof UserStore.state;
};

// Declare the store's getter payload. If you're gonna have `modules` declared, then the getters will be set at runtime.
// Use an empty object here to avoid duplicate-key errors
const getters = {} as RootGetters & GettersImpl<RootState, RootGetters>; // Note the intersect

const { store, moduleActionContext, moduleGetterContext } = createDirectStore({
  modules: {
    accounts: AccountStore,
    accountUsers: AccountUserStore,
    currentUser: CurrentUserStore,
    currentAccount: CurrentAccountStore,
    documents: DocumentStore,
    messages: MessagesStore,
    permissions: PermissionStore,
    ui: UserInterfaceStateStore,
    users: UserStore
  },
  getters // Explicitly add our getters to the root store
});

export default store;
export type State = typeof store.state;
export type Getters = typeof store.getters; // This should now be populated correctly!

我最新的工作理论是 direct-vuex 依赖于 GettersImpl&lt;State, Getters&gt; 的良好类型。由于某种原因,TypeScript 无法从我们复杂的模块结构中推断出这一点,因此我们需要提示它。

相当多的样板,新的存储模块需要插入更多的地方,更不用说现有的带有getter的模块需要添加到RootGetters类型和getters对象中,但至少我们得到了以这种方式完全输入组件。

如果我发现一种更简洁的方法来获得这种效果,我会更新这个答案。

【讨论】:

    猜你喜欢
    • 2020-05-26
    • 2020-12-26
    • 1970-01-01
    • 2017-04-15
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 2015-06-27
    • 2016-02-17
    相关资源
    最近更新 更多