Type Error When Using Typescript with React-Redux

I am trying to use response-redux with typescript, and I am getting a type error when I try to insert the details with connect () and mapStateToProps.

My component is as follows:

function mapStateToProps(state) { return { counter: state.counter }; } function mapDispatchToProps(dispatch) { return { incr: () => { dispatch({type: 'INCR', by: 2}); }, decr: () => { dispatch({type: 'INCR', by: -1}); } }; } export default class Counter extends React.Component<HelloProps, any> { render() { return ( <div> <p> <label>Counter: </label> <b>#{this.props.counter}</b> </p> <button onClick={e => this.props.incr() }>INCREMENT</button> <span style={{ padding: "0 5px" }}/> <button onClick={e => this.props.decr() }>DECREMENT</button> ); } } export default connect(mapStateToProps, mapDispatchToProps)(Counter); 

The store is as follows

 let store = createStore( (state:HelloState, action:HelloAction) => { switch (action.type) { case 'INCR': return {counter: state.counter + action.by}; default: return state; } }, 

Finally, I determined that my types are:

 interface HelloProps { counter?: number; incr?: () => any; decr?: () => any; } interface HelloState { counter:number; } interface HelloAction { type:string, by:number; } 

When I try to compile the code, I get the following error:

 (39,61): error TS2345: Argument of type 'typeof Counter' is not assignable to parameter of type 'ComponentClass<{ counter: any; } & { incr: () => void; decr: () => void; }> | StatelessComponent<...'. Type 'typeof Counter' is not assignable to type 'StatelessComponent<{ counter: any; } & { incr: () => void; decr: () => void; }>'. Type 'typeof Counter' provides no match for the signature '(props?: { counter: any; } & { incr: () => void; decr: () => void; }, context?: any): ReactElement<any>' 

Interestingly, the code still works, although it raises a type error. In addition, changing the prop component interface on any one also solves the problem. It seems that the type system does not understand that these two objects are combined by two mapped functions.

+7
reactjs redux react-redux typescript
source share
2 answers

I found the answer in the second and last post on this Github issue . Without a type parameter on mapStateToProps and / or mapDispatchToProps or on connect it will lead to the intersection of the returned types of the two map functions.

+7
source share

To maintain type safety, you can divide your details into parts, one is responsible for ordinary details and one for dispatchers:

 import * as React from 'react'; import {connect} from 'react-redux'; interface StateProps { textPros: string, optionalText?: string, } interface DispatchProps { onClick1: Function, } class MyComp extends React.Component<StateProps & DispatchProps , any> { render() { return (<div onClick={this.props.onClick1}>{this.props.textPros}</div>); } } const mapStateToProps = (state: any, ownProp? :any):StateProps => ({ textPros: "example text", }); const mapDispatchToProps = (dispatch: any):DispatchProps => ({ onClick1: () => { dispatch({ type: 'CLICK_ACTION'}); } }); export default connect(mapStateToProps, mapDispatchToProps)(MyComp); 

For those looking for a quick workaround: just add β€œlike anyone” to the base component.

 export default connect(mapStateToProps, mapDispatchToProps)(MyComp as any); 
+30
source share

All Articles