I am not able to figure out the type of my mapDispatchToProps. Check below in the SignInComponent const mapDispatchToProps.
Seems simple as the functions takes signIn() as a parameter, from whom type I have availble. However I was not able to figure that out.
This is my autAction.ts:
import firebase from 'firebase/app'
import { Dispatch } from 'react';
type AuthAction = {
type: string,
err?: unknown
}
export const signIn = (credentials: {email:string, password:string}) => {
return (dispatch: Dispatch<AuthAction>) => {
firebase.auth().signInWithEmailAndPassword(
credentials.email,
credentials.password
).then(() => {
dispatch({ type: 'LOGIN_SUCCESS'})
}).catch((err) => {
dispatch({ type: 'LOGIN_ERROR', err})
});
}
}
And this is my SignIn component:
import React, { BaseSyntheticEvent, Component } from 'react'
import { connect } from 'react-redux';
import { signIn } from '../../store/actions/authActions';
type IConnectedDispatch = {
signIn: typeof signIn
}
interface IMyComponentProps {
signIn: (credentials: {email:string, password:string}) => void;
}
class SignIn extends Component<IMyComponentProps> {
state = {
email:'',
password:''
}
handleChange = (e:BaseSyntheticEvent) => {
this.setState({
[e.target.id]: e.target.value
});
}
handleSubmit = (e:BaseSyntheticEvent) => {
e.preventDefault();
//console.log(this.state);
this.props.signIn(this.state);
}
render() {
return (
<div className="container">
<form onSubmit={this.handleSubmit} className="white">
<h5 className="grey-text text-darken-3">Sing In</h5>
<div className="input-field">
<label htmlFor="email">Email</label>
<input type="email" id="email" onChange={this.handleChange}/>
</div>
<div className="input-field">
<label htmlFor="password">Password</label>
<input type="password" id="password" onChange={this.handleChange}/>
</div>
<div className="input-field">
<button className="btn pink lighten-1 z-depth-0">Login</button>
</div>
</form>
</div>
)
}
}
type AuthAction = {
type:string,
err?: unknown
}
const mapDispatchToProps = (dispatch: any): IConnectedDispatch => { //TYPE CHALLENGE HERE.
return {
signIn: (credentials:{ email:string, password:string}) => dispatch(signIn(credentials))
}
}
export default connect<React.FunctionComponent>(null,mapDispatchToProps)(SignIn)
As shown in @liamgbs' answer, your
mapDispatchToPropsisn't really necessary, but I do want to answer your questions regarding the typescript issues.mapDispatchToPropsis a function which takesdispatchas an argument and returns a keyed object of props. So the type is essentially(dispatch: Dispatch).The question is which
Dispatchdefinition to use here, as multiple packages have their own typings for it. The more basic definitions ofDispatchfromreactandreduxexpect thatdispatchwill only be called with a plain action object. The return value from yoursignInaction creator is instead a function ofdispatch(a "thunk"). So you need to use typings from theredux-thunkpackage.{signIn: typeof signIn}is also not quite right because you are callingsignInrather than just returning it. The actual interface is yourIMyComponentProps, wheresignInis avoidfunction.Annoyingly,
ThunkDispatchrequires you to set all three generics. That firstanyrepresents the type of your redux state, so you could replace that with an actual type if you want. Theneveris the extra args in your action creator which you aren't using.