javascriptflowtype

How to add default generic type - typing createReducer with Flow


Here you can see a handy createReducer() How would you type it using Flow?

Here is my example

// @flow
import type { TAction as TActionDefault } from '../actions/types';

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

type TReducer<TState, TAction> = (state: TState, action: TAction) => TState


export default function createReducer<TState, TAction>(
  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)
    } else {
      return state
    }
  }
}

But there is an issue here

Cannot get `action.type` because property `type` is missing in `TAction` [1]. (References: [1])

And flow doesn't let me to give default type value to TAction.

So what do you do in this and similar cases?


Solution

  • Flow does let you add a default for the generic

    createReducer<TState, TAction = TActionDefault>
    

    The above compiles as of June 2019. See https://github.com/facebook/flow/issues/6875