Vue 3 + Vuex + TypeScript
Требуется небольшая помощь с типизацией на финальном шаге.
Имеем вот такой store
export const store = createStore<State>({
plugins: process.env.NODE_ENV === 'development' ? [createLogger()] : [],
state,
mutations,
actions,
getters,
});
export type Store = Omit<
VuexStore<State>,
'getters' | 'commit' | 'dispatch'
> & {
commit<K extends keyof Mutations, P extends Parameters<Mutations[K]>[1]>(
key: K,
payload: P,
): ReturnType<Mutations[K]>;
} & {
dispatch<K extends keyof Actions, P extends Parameters<Actions[K]>[1]>(
key: K,
payload: P,
): ReturnType<Actions[K]>;
} & {
getters: {
[K in keyof Getters]: ReturnType<Getters[K]>
};
}
export function useStore() {
return store as Store;
}
Проблема с нагрузкой в Мутациях и Экшенах. Проблема идентичная, так что рассмотрим только Мутации. Вот так они выглядят.
type Mutations = {
[MutationNames.TestBoolean](state: State, value: boolean): void;
[MutationNames.TestNumber](state: State, value: number): void;
}
В текущей конфигурации типизация работает просто на ура. Проблема возникает тогда, когда мы решаем сделать мутацию без входящего значения
type Mutations = {
[MutationNames.TestBoolean](state: State, value: boolean): void;
[MutationNames.TestNumber](state: State, value: number): void;
[MutationNames.NewMutations](state: State): void;
}
Естественно и ожидаемо при вызове этой мутации в компоненте компилятор начинает ругается, что "payload" обязателен.
Вроде как решение очевидно - сделать payload не обязательным.
commit<K extends keyof Mutations, P extends Parameters<Mutations[K]>[1]>(
key: K,
payload?: P,
): ReturnType<Mutations[K]>;
Но тогда возникает другая проблема - мутации с полезной нагрузкой так же можно будет вызвать без неё. Вот такая штука в компоненте не вызовет возражений у компилятора.
store.commit(MutationNames.TestBoolean);
И вообщем-то, почему это происходит так же понятно. Но вот как описать тип Store чтобы все работало как надо - не ясно.