I am trying to use react-redux with typescript and I'm getting a type error when I try to inject props using connect() and mapStateToProps.
My component looks like this:
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 looks like this
let store = createStore(
(state:HelloState, action:HelloAction) => {
switch (action.type) {
case 'INCR':
return {counter: state.counter + action.by};
default:
return state;
}
},
Finally, I have defined my types to be:
interface HelloProps {
counter?: number;
incr?: () => any;
decr?: () => any;
}
interface HelloState {
counter:number;
}
interface HelloAction {
type:string,
by:number;
}
When I try and 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 even though it throws the type error. Also, changing the component's prop interface to any also solves the issue. It seems like the type system doesn't understand that the two objects are merged by the two mapped functions.