up 0 down

Пытаясь сделать createReducer с типами потока.

Вот пример

// @flow
export type TActionWithPayload<TPayload = any> = {
  +type: string,
  payload: TPayload
};

export type TAction = {
  +type: string
};


type TActionDefault = TAction

export type THandlers<TState, TAction> = {
  [key: string]: (state: TState, action: TAction) => TState
}

export type TReducer<
  TState,
  TAction = TActionWithPayload<any> | TActionDefault
  > = (state: TState, action: TAction) => TState

function createReducer<
TState,
TAction: TActionDefault | TActionWithPayload <any>
>(
  initialState: TState,
  handlers: THandlers<TState, TAction>
): TReducer < TState, TAction > {
  return function reducer(
    state: TState = initialState,
    action: TAction
  ): TState {
    if (handlers[action.type]) {
      return handlers[action.type](state, action);
    }
    return state;
  };
}

export default createReducer;

export type TGetState<TState> = () => TState;
export type TThunkAction =
  (dispatch: TDispatch, getState: TGetState<any>) => any;
export type TPromiseAction = Promise<TActionWithPayload<any> | TAction>;
export type TDispatch = (
  action: TActionWithPayload<any> | TThunkAction | TPromiseAction | TAction
  ) => any;

И вот пример, как это используется.

// @flow
import type {
  TReducer,
  THandlers,
  TActionWithPayload,
} from '../../../shared/utils/reduxHelpers';
import type {
  TUser,
} from '../../../shared/models/User';
import createReducer from '../../../shared/utils/reduxHelpers';

export type TState = ?$ReadOnly<TUser>

export const ON_LOGIN = 'ON_LOGIN';

const handlers: THandlers<TState, TActionWithPayload<TState>> = {
  [ON_LOGIN]: (state, action) => action.payload,
};

const reducer: TReducer<TState> = createReducer(null, handlers);

export default reducer;

Но flow дает эту ошибку

Cannot assign createReducer(...) to reducer because property payload is missing in TAction [1] but exists in
TActionWithPayload [2] in the second argument.

     src/features/Auth/redux/index.js
 [2] 16│ const handlers: THandlers<TState, TActionWithPayload<TState>> = {
     17│   [ON_LOGIN]: (state, action) => action.payload,
     18│ };
     19│
     20│ const reducer: TReducer<TState> = createReducer(null, handlers);
     21│
     22│ export default reducer;
     23│

     src/shared/utils/reduxHelpers.js
 [1] 20│   TAction = TActionWithPayload<any> | TActionDefault

Не уверен, почему эта ошибка происходит. Как бы вы правильно набрали createReducer