Тип карты действия редуктора - PullRequest
0 голосов
/ 09 мая 2019

Реализация функции редуктора высшего порядка (createReducer) довольно проста, однако написание определения типа (CreateReducer) является более сложным, как показано ниже

// HELPER TYPES

type SimpleAction<ActionType> = {
  type: ActionType
}
interface PayloadAction<Payload, AT> extends SimpleAction<AT> {
  payload: Payload
}

type Reducer<State, Action extends SimpleAction<Action['type']>> = (state: State, action: Action) => State
type PureReducer<State, Action extends SimpleAction<Action['type']>> = (state: State, action: Action) => State


// COUNT EXAMPLE TYPES

type Count = number
const increment = 'increment'
type IncrementAction = SimpleAction<typeof increment>


type ActionReducerMap<State, Action extends SimpleAction<Action['type']>> = { [ActionType in Action['type']]: PureReducer<State, SimpleAction<ActionType>> }

const countActionReducerMap: ActionReducerMap<Count, IncrementAction> = {
  [increment]: (count, { type }) => count + 1,
}

type CreateReducer = <State>(initialState: State) => <Action extends SimpleAction<Action['type']>>(arm: ActionReducerMap<State, Action>) => Reducer<State, Action>

const createReducer: CreateReducer = initialState => arm => (state = initialState, action) => {
  const actionTypes = Object.keys(arm)

  if (actionTypes.includes(action.type)) {
    return arm[action.type](state, action)
  } else {
    return state
  }
}

// Count reducer using previously created count action reducer map
const countReducer = createReducer(0)(countActionReducerMap)

// Seemingly the same reducer except that the action reducer map is passed as an object literal inline
const countReducerInline = createReducer(0)({
  // ERROR Parameter 'count' implicitly has an 'any' type
  [increment]: (count, { type }: IncrementAction) => count + 1,
})

// Both reducers work as expected
console.log(countReducer(1, { type: increment })) // 2
console.log(countReducerInline(1, { type: increment })) // 2

Как бы вы исправили ошибку типа в отношениифункция countReducerInline?Или как бы вы реализовали тип CreateReducer?

...