行动减速器地图类型

时间:2019-05-09 12:59:13

标签: typescript types redux reducers

实现高阶缩减器(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类型?

0 个答案:

没有答案