flow-typed: react-redux type error when only passing in only mapStateToProps on flow v0.55.0

Previously on flow v0.54.1, the following code checked out fine

// @flow
import { connect, type Connector } from 'react-redux'

type State = {
  val: string,
}
type OwnProps = {
  other: string,
}
type Props = {
  other: string,
  val: string,
}

const mapStateToProps = (state: State) => {
  return {
    val: state.val,
  }
}

const connector: Connector<OwnProps, Props> = connect(mapStateToProps)

After upgrading flow to v0.55.0, flow gives an error

Error: src/components/body/custom-events/department-transfer-container.js:29
 29: const connector: Connector<OwnProps, Props> = connect(mapStateToProps)
                                                   ^^^^^^^^^^^^^^^^^^^^^^^^ function call. Could not decide which case to select
 29: const connector: Connector<OwnProps, Props> = connect(mapStateToProps)
                                                   ^^^^^^^ intersection type
  Case 3 may work:
                                 v--------------
   78:   declare function connect<S, A, OP, SP>(
   79:     mapStateToProps: MapStateToProps<S, OP, SP>,
   80:     mapDispatchToProps: Null,
  ...:
   83:   ): Connector<OP, $Supertype<SP & { dispatch: Dispatch<A> } & OP>>
         ----------------------------------------------------------------^ polymorphic type: function type. See lib: flow-typed/npm/react-redux_v5.x.x.js:78
  But if it doesn't, case 5 looks promising too:
                                 v------------------
   92:   declare function connect<S, A, OP, SP, DP>(
   93:     mapStateToProps: MapStateToProps<S, OP, SP>,
   94:     mapDispatchToProps: MapDispatchToProps<A, OP, DP>,
  ...:
   97:   ): Connector<OP, $Supertype<SP & DP & OP>>
         -----------------------------------------^ polymorphic type: function type. See lib: flow-typed/npm/react-redux_v5.x.x.js:92
  Please provide additional annotation(s) to determine whether case 3 works (or consider merging it with case 5):
   14: const mapStateToProps = (state: Object, ownProps: OwnProps) => {
                                                                     ^ return

I can resolve the error by passing in an empty mapDispatchToProps like so

const mapDispatchToProps = (dispatch: Dispatch<*>) => {
  return {}
}
const connector: Connector<OwnProps, Props> = connect(
  mapStateToProps,
  mapDispatchToProps
)

but hoping there might be a way to adjust the libdef to support not passing in mapDispatchToProps like before.

About this issue

  • Original URL
  • State: closed
  • Created 7 years ago
  • Reactions: 37
  • Comments: 23 (14 by maintainers)

Commits related to this issue

Most upvoted comments

Annotating mapStateToProps has worked for me.

import type { MapStateToProps } from "react-redux"

const mapStateToProps: MapStateToProps<*, *, *> = (state: StateType) => {
  return ...
}

export default connect(mapStateToProps)(...)

Flow infers what version of connect to use this way.

We were wrestling with this issue, and it turned out the problem was that we weren’t declaring a return type for our mapStateToProps function. Adding a signature like

function mapStateToProps(state: State): StateProps {
    return …;
}

resolved the type error. It was just an oversight on our part.

those of you battling the issue, this worked like a charm:

// BEFORE
const connector: Connector<OwnProps, Props> = connect((state: ReduxState, props: OwnProps) => ({
  fmt: dateFormatter(state, props),
}));

// AFTER
// just add ': *' to your map state to props function as the return type
const connector: Connector<OwnProps, Props> = connect((state: ReduxState, props: OwnProps): * => ({
  fmt: dateFormatter(state, props),
}));

To have the same functionality as when you’re not providing a mapDispatchToProps (or using null) to have dispatch added to the props for you, here’s what you can do to work around this bug:

export const ConnectedApp = connect(                                                                                                                                                                                                      
  mapStateToProps,                                                                                                                                                                                                                                     
  (dispatch: Dispatch) => ({dispatch: dispatch}),                                                                                                                                                                                         
)(App);

I’m seeing the same errors with Flow 0.56.0. I found that the | DP part will lead to Flow allowing empty mapDispatchToProps to be considered, thus lead Flow to think “case 5 looks promising”.

  declare type MapDispatchToProps<A, OP: Object, DP: Object> =
    | ((dispatch: Dispatch<A>, ownProps: OP) => DP)
    | DP;

Removing | DP seems to work but it will likely lead to other issues:

  declare type MapDispatchToProps<A, OP: Object, DP: Object> =
    (dispatch: Dispatch<A>, ownProps: OP) => DP;