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 чтобы все работало как надо - не ясно.


Ответы (0 шт):