2
votes

Flow declaration for redux connect function is the following:

declare export function connect<-P, -OP, -SP, -DP, S, D>(
  // ...
)

it's taken from: https://github.com/flow-typed/flow-typed/blob/master/definitions/npm/react-redux_v7.x.x/flow_v0.104.x-/react-redux_v7.x.x.js

Please correct me if I wrong:

  • P - stands for Props. Just all props that component should eventually receive.

  • OP - stands for OwnProps. Props that should be passed to connected component(i.e. not derived from the state).

  • SP - stands for StateProps. Props that are derived from state, which mapStateToProps must return.

  • DP - stands for DispatchProps. Props that are derived from dispatch, which mapDispatchToProps must return.

  • S - stands for State. Type of state to pass in mapStateToProps.

  • D - stands for Dispatch. Type of dispatch to pass in mapDispatchToProps.

If all the above statements are correct, then everything seems clear and logical to me.

So, when I'm trying to pass those generics:

/* @flow */

import React from 'react';
import { connect } from 'react-redux';
import * as ActionCreators from './actionCreators';
import type { Todo } from './types';
import type { State } from './reducers';

type OwnProps = {||};

type StateProps = {|
  +todos: Array<Todo>;
|};

type DispatchProps = $ReadOnly<typeof ActionCreators>

type Props = {|
  ...OwnProps;
  ...StateProps;
  ...DispatchProps;
|};

export const TodoList = (props: Props) => (
  <div>
    // ...
  </div>
);

const mapStateToProps = (state: State) => ({
  todos: state.visibleTodos,
});

const mapDispatchToProps = ActionCreators; // redux will automatically call `bindActionCreators`

export default connect<Props, OwnProps, StateProps, DispatchProps, State, _>(
  mapStateToProps,
  mapDispatchToProps
)(TodoList);

I get the following output from flow, why?

Cannot call connect because:
 - Either property todos is missing in object type [1] but exists in StateProps [2] in type argument SP.
 - Or property addTodo is missing in object type [3] but exists in DispatchProps [4] in type argument DP.
 - Or property todos is missing in object type [5] but exists in StateProps [2] in type argument SP.
 - Or property todos is missing in object type [6] but exists in StateProps [2] in type argument SP.

        src/components/TodoList/index.jsx
         72|
         73| const mapDispatchToProps = ActionCreators;
         74|
 [2][4]  75| export default connect<Props, OwnProps, StateProps, DispatchProps, State, _>(
         76|   mapStateToProps,
         77|   mapDispatchToProps,
         78| )(TodoList);

        flow-typed/npm/react-redux_v7.x.x.js
    [1] 148|   declare export function connect<-P, -OP, -SP: {||}, -DP: {||}, S, D>(
           :
    [3] 156|   declare export function connect<-P, -OP, -SP, -DP: {||}, S, D>(
           :
    [5] 166|   declare export function connect<-P, -OP, -SP: {||}, -DP, S, D>(
           :
    [6] 176|   declare export function connect<-P, -OP, -SP: {||}, -DP, S, D>(

Found 1 error

Thank You in advance.

1

1 Answers

0
votes

It turns out that's the flow bug with type inference. I solved this problem by explicitly adding StateProps return type to mapStateToProps.