经过反复试验,我得出如下结论:
// 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
对象,但至少我们可以用这种方式在组件中进行完全类型化。
如果我找到一个更简洁的方法来获得这个效果,我会更新这个答案。