代码之家  ›  专栏  ›  技术社区  ›  rostamiani

`direct vuex`getters的`{}`类型没有属性,但在运行时填充

  •  0
  • rostamiani  · 技术社区  · 5 年前

    我正在使用typescript实现我的VueJS存储+ direct-vuex 打包并在使用吸气剂时遇到问题。

    类型 store.getters {} 没有财产。但在运行时它有属性。 UserModule.getters 类型正确,但存储不:

    用户模块.getters:

    enter image description here

    商店吸气剂:

    enter image description here

    储存/索引.ts:

    Vue.use(Vuex);
    
    const {
      store,
      rootActionContext,
      moduleActionContext,
      rootGetterContext,
      moduleGetterContext,
    } = createDirectStore({
      state: {
        CurrentUser: {} as User,
      },
      modules: {
        user: userModule,
        chat: chatModule,
      },
    });
    
    console.log(store.getters);
    

    商店/模块/用户/索引.ts:

    export const userModule = defineModule({
      state: {
        userList: [],
        currentUser: {},
      } as UserStates,
    
      actions: userActions,
      mutations: userMutations,
      getters: 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"
        );
      },
    });
    
    0 回复  |  直到 5 年前
        1
  •  1
  •   AverageHelper    4 年前

    经过反复试验,我得出如下结论:

    // 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<State, Getters>

    这是一个相当多的样板,新的store模块需要插入到更多的地方,更不用说现有的带有getter的模块需要添加到 RootGetters 类型和 getters 对象,但至少我们可以用这种方式在组件中进行完全类型化。

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