This should be easy but it's eluding me at the moment but I feel like it should be a simple fix. I am currently using redux with typescript and using redux-thunk for async action creators.
The set up is simple. Here is the code I am using for login:
export function requestAuthenticationAsync(email: string, password: string) {
return (dispatch: ThunkDispatch<IState, undefined, IAction>): Promise<void> => {
dispatch(requestAuthentication());
return postAuthentication(email, password).then((response) => {
dispatch(receiveAuthentication());
return response.json();
}).then((data) => {
dispatch(receiveUser(data));
});
};
}
The ideal situation is that I could call this in a .tsx file using .then to navigate elsewhere when the login is successful.
So, this works as you would expect it to when I do something like this in a component:
const { dispatch } = store;
dispatch(requestAuthenticationAsync('email', 'password')).then(() => {
// navigate somewhere
});
However, when I use connect and mapDispatchToProps from react-redux like so:
import './Gateway.scss';
import * as React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import { requestAuthenticationAsync } from './actions';
import { withRouter } from 'react-router-dom';
const mapDispatchToProps = (dispatch) => {
return {
requestAuthenticationAsync: bindActionCreators(requestAuthenicationAsync, dispatch)
};
};
const mapStateToProps = (state) => {
return {
authenticated: state.authentication.authenticated
};
};
class Gateway extends React.Component<{
authenticated: boolean;
requestAuthenticationAsync: typeof requestAuthenticationAsync;
}, {
email: string;
password: string;
}> {
constructor(props) {
super(props);
this.state = {
email: '',
password: ''
};
}
onGatewaySubmit = (event) => {
event.preventDefault();
const { requestAuthenticationAsync } = this.props;
const { email, password } = this.state;
requestAuthenticationAsync(email, password).then(() => {
console.log('done');
});
};
onEmailValueChange = (event) => {
this.setState({
email: event.target.value
});
};
onPasswordValueChange = (event) => {
this.setState({
password: event.target.value
});
};
render() {
return (
<div id='gateway'>
<form onSubmit={ this.onGatewaySubmit }>
<input
className='email'
onChange={ this.onEmailValueChange }
placeholder='email'
type='text' />
<input
className='password'
onChange={ this.onPasswordValueChange }
placeholder='password'
type='password' />
<input type='submit' value='Submit' />
</form>
</div>
);
}
}
export default withRouter(connect(mapStateToProps, mapDispatchToProps)(Gateway));
I get the following error:
TS2339: Property 'then' does not exist on type '(dispatch: ThunkDispatch<IState, undefined, IAction>) => Promise<void>'.
What gives? How do I make TypeScript happy in this situation so I can use a promise with .then?