text: // @flow
  import React from "react";
  import { connect } from "react-redux";
  
  export let e = []
  
  function onlyDispatchFunction_samePropsAreOK() {
    type State = {||}
    type Action = {|
      type: 'action'
    |};
    type DispatchAction = Action => Action;
    type Thunk = (Dispatch, State) => Promise<number>
    type DispatchThunk = Thunk => Promise<number>
    type Dispatch = DispatchAction & DispatchThunk
  
    const action = (): Action => ({ type: 'action' });
    const thunk = (): Thunk => (d: Dispatch) => Promise.resolve(1);
    type DispatchProps = {|
      action: typeof action,
      thunk: () => Promise<number>,
    |};
    type MapDispatchToPropsFn = Dispatch => DispatchProps;
    const mapDispatchToProps: MapDispatchToPropsFn = (dispatch) => ({
      action: () => dispatch(action()),
      thunk: () => dispatch(thunk())
    });
  
    type Props = { // in the case of a function passed to `connect()` Flow infers
    // the same type of function is both the Props and DispatchProps objects
    // (see the testDispatchThunk() to get the difference)
    ...DispatchProps, ... };
    class Com extends React.Component<Props> {}
  
    const Connected = connect<Props, {||}, _,DispatchProps,_,Dispatch>(null, mapDispatchToProps)(Com);
    e.push(Connected);
    <Connected />;
  }
  
  function onlyDispatchObject_differentDispatchPropsAreOK() {
    type State = {||}
    type Action = {|
      type: 'action'
    |};
    type DispatchAction = Action => Action;
    type Thunk = (Dispatch, State) => Promise<number>
    type DispatchThunk = Thunk => Promise<number>
    type Dispatch = DispatchAction & DispatchThunk
  
    const action = (): Action => ({ type: 'action' });
    const thunk = (): Thunk => (d: Dispatch) => Promise.resolve(1);
  
    type DispatchProps = {|
      action: typeof action,
      // here the property returns a thunk...
      thunk: () => Thunk,
    |};
    const mapDispatchToProps = {
      action,
      thunk
    };
  
    type Props = {
      action: typeof action,
      // ... and here the property returns a return value of thunk
      // as dispatch calls it for us with `dispatch` and `getState`
      thunk: () => Promise<number>,
      ...
    };
    class Com extends React.Component<Props> {}
  
    const Connected = connect<Props, {||}, _,DispatchProps,_,Dispatch>(null, mapDispatchToProps)(Com);
    e.push(Connected);
    <Connected />;
  }
  
  function onlyDispatchObject_sameDispatchPropsAreErroneous() {
    type State = {||}
    type Action = {|
      type: 'action'
    |};
    type DispatchAction = Action => Action;
    type Thunk = (Dispatch, State) => Promise<number>
    type DispatchThunk = Thunk => Promise<number>
    type Dispatch = DispatchAction & DispatchThunk
  
    const action = (): Action => ({ type: 'action' });
    const thunk = (): Thunk => (d: Dispatch) => Promise.resolve(1);
  
    type DispatchProps = {|
      action: typeof action,
      //$FlowExpectedError here the property returns a thunk...
      thunk: () => Thunk,
    |};
    const mapDispatchToProps = {
      action,
      thunk
    };
  
    type Props = { // trying to pass the not passed to dispatch types (against the redux dispatch monad)
    ...DispatchProps, ... };
    class Com extends React.Component<Props> {}
  
    const Connected = connect<Props, {||}, _,DispatchProps,_,Dispatch>(null, mapDispatchToProps)(Com);
    e.push(Connected);
    <Connected />;
  }
  
  function stateAndDispatchObject_differentDispatchPropsAreOK() {
    type State = {|
      state1: 'state1'
    |}
    type Action = {|
      type: 'action'
    |};
    type DispatchAction = Action => Action;
    type Thunk = (Dispatch, State) => Promise<number>
    type DispatchThunk = Thunk => Promise<number>
    type Dispatch = DispatchAction & DispatchThunk
  
    const action = (): Action => ({ type: 'action' });
    const thunk = (): Thunk => (d: Dispatch) => Promise.resolve(1);
  
    type StateProps = {|
      state1: 'state1',
    |};
    const mapStateToProps = state => ({
      state1: state.state1
    })
  
    type DispatchProps = {|
      action: typeof action,
      // here the property returns a thunk...
      thunk: () => Thunk,
    |};
    const mapDispatchToProps = {
      action,
      thunk
    };
  
    type Props = {
      ...StateProps,
      action: typeof action,
      // ... and here the property returns a return value of thunk
      // as dispatch calls it for us with `dispatch` and `getState`
      thunk: () => Promise<number>,
      ...
    };
    class Com extends React.Component<Props> {}
  
    const Connected = connect<Props, {||}, _,DispatchProps,_,Dispatch>(mapStateToProps, mapDispatchToProps)(Com);
    e.push(Connected);
    <Connected />;
  }
  
  function stateAndDispatchObject_sameDispatchPropsAreErroneous() {
    type State = {||}
    type Action = {|
      type: 'action'
    |};
    type DispatchAction = Action => Action;
    type Thunk = (Dispatch, State) => Promise<number>
    type DispatchThunk = Thunk => Promise<number>
    type Dispatch = DispatchAction & DispatchThunk
  
    const action = (): Action => ({ type: 'action' });
    const thunk = (): Thunk => (d: Dispatch) => Promise.resolve(1);
  
    type StateProps = {|
      state1: 'state1',
    |};
    const mapStateToProps = state => ({
      state1: state.state1
    })
  
    type DispatchProps = {|
      action: typeof action,
      //$FlowExpectedError here the property returns a thunk...
      thunk: () => Thunk,
    |};
    const mapDispatchToProps = {
      action,
      thunk
    };
  
    type Props = {
      ...StateProps,
      // trying to pass the not passed to dispatch types (against the redux dispatch monad)
      ...DispatchProps,
      ...
    };
    class Com extends React.Component<Props> {}
  
    const Connected = connect<Props, {||}, _,DispatchProps,_,Dispatch>(mapStateToProps, mapDispatchToProps)(Com);
    e.push(Connected);
    <Connected />;
  }
  