Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Correct type declaration for mapStateToProps of Redux connect (TypeScript 2)

I have a Redux store and want to connect it. Here an extract from my container component:

interface IProps  {
  states: IAppState;
  actions: IAppProps;
}
// mapping state to the props
const mapStateToProps = ( state: IAppState, ownProps = {} ) => ({
  states: state
});
// mapping actions to the props
const mapDispatchToProps = ( dispatch: Redux.Dispatch<IAppState> ) => ({
  actions: Redux.bindActionCreators( actions, dispatch )
});

// connect store to App
@connect<IAppState, IAppProps, any>(
  mapStateToProps,
  mapDispatchToProps
)
export default class App extends React.Component<IProps, {}> {
//...
}

When compiling I receive the following issue:

error TS2345: Argument of type '(state: IAppState, ownProps?: {}) => { states: IAppState; }' is not assignable to parameter of type 'MapStateToPropsParam<IAppState, any>'.
  Type '(state: IAppState, ownProps?: {}) => { states: IAppState; }' is not assignable to type 'MapStateToPropsFactory<IAppState, any>'.
    Type '{ states: IAppState; }' is not assignable to type 'MapStateToProps<IAppState, any>'.
      Type '{ states: IAppState; }' provides no match for the signature '(state: any, ownProps?: any): IAppState'.

I'm using @types/[email protected] that exposes MapStateToProps interface. I would think that my mapStateToProps confronts this interface... Yet something is wrong. Any ideas what is that?

like image 622
Dmitry Sheiko Avatar asked Jun 23 '17 11:06

Dmitry Sheiko


People also ask

What is mapStateToProps in React Redux?

As the first argument passed in to connect , mapStateToProps is used for selecting the part of the data from the store that the connected component needs. It's frequently referred to as just mapState for short. It is called every time the store state changes.

What is mapStateToProps and mapDispatchToProps in React Redux?

The mapStateToProps and mapDispatchToProps deals with your Redux store's state and dispatch , respectively. state and dispatch will be supplied to your mapStateToProps or mapDispatchToProps functions as the first argument.

What is the purpose of the connect () function in Redux?

The React Redux connect() API is used for creating container elements that are connected to the Redux store. The Redux store is derived from the topmost ancestor of the component using React Context. If you are only creating a presentational component, you have no need for connect() .


2 Answers

Well, seems like @types/react-redux accepts mapStateToProps to return exact the same type as took in. I wanted it to modify it for props during mapping like { states: AppStateTree }. Instead I've modified the state tree combineReducers({ states: myReducer }). So this code works fine:

interface IRootState {
  state: IAppState;
}

const mapStateToProps = ( state: IRootState ) => state;

const mapDispatchToProps = {
  toggleOpenAddFeed
};

type IProps = IRootState & typeof mapDispatchToProps;

class App extends React.Component<IProps, {}> {
 render() {
    return (
      <div className="main-wrapper">
         <Mycomponent store={this.props} />
      </div>
    );
  }
}

export default connect( mapStateToProps, mapDispatchToProps )( App );
like image 185
Dmitry Sheiko Avatar answered Sep 28 '22 06:09

Dmitry Sheiko


ownProps doesn't have any type. You must give a type to it.

const mapStateToProps = ( state: IAppState, ownProps: any = {} )
like image 35
Ematipico Avatar answered Sep 28 '22 06:09

Ematipico