I'm having some inconveniences with typescript and redux-thunk actions.
Basically my components make heavy use of react-redux connect to bind action creators, the problem is, when I create the interface for this redux actions within the component, I have to re-declare the function definition because it gets lost on the connect call.
Here is a sample code:
Action Creator
import api from './api';
import { Dispatch } from 'redux';
import { IReduxAction } from 'model';
export const FETCH_ENTITY = 'location/FETCH_ENTITY';
export function fetchEntity(id: string) {
return (dispatch: Dispatch<IReduxAction>) => {
dispatch({type: `${FETCH_ENTITY}_REQUEST`, payload: {id}});
return api.fetchEntity(id)
.then((res) => {
dispatch({ type: `${FETCH_ENTITY}_DONE`, payload: res });
return res;
})
.catch((err) => {
dispatch({type: `${FETCH_ENTITY}_FAIL`, payload: err, error: true});
throw err;
});
};
}
Component
import * as React from 'react';
import { bindActionCreators } from 'redux';
import { connect } from 'react-redux';
import {
fetchEntity,
} from 'actions';
interface IStateProps {
startingEntities: any[];
}
interface IDispatchProps {
fetchEntity: (id: string) => Promise<any>; // <- this is what I'm trying to get rid of, basically whenever I change the action creator I have to change this definition everytime
}
class Dashboard extends React.Component<IStateProps & IDispatchProps, void> {
public render() {
return (<div>...RENDER SOMETHING...</div>);
}
}
const mapStateToProps = (state: any, ownProps: any) => {
const startingEntities = foo(); // not important
return {
startingEntities,
};
};
const mapDispatchToProps = (dispatch: any) => {
return bindActionCreators({
fetchEntity
}, dispatch);
};
export default connect<IStateProps, IDispatchProps, void>(mapStateToProps, mapDispatchToProps)(Dashboard);
Is there anyway to declare this binded action creator without having to re-declare it everytime on each file?
You don't need to define the function type again. You can use typeof
:
interface IDispatchProps {
fetchEntity: typeof fetchEntity
}
I'm not very familiar with TypeScript (mostly have just done index.d.ts
files for library interfaces) but you should be able to get the type system to do the work for you by correctly typing fetchEntity
and exporting it for IDispatchProps
to use. Something like
//...
import { ThunkAction } from 'redux-thunk'
//...
export interface FetchEntity {
(id: string): ThunkAction<Promise<any>, IReduxAction, any>;
}
//...
export const fetchEntity: FetchEntity = (id: string) => {
return (dispatch: Dispatch<IReduxAction>) => {
//...
};
}
And then you can import it and use the same definition
//...
import {
fetchEntity,
FetchEntity
} from 'actions';
//...
interface IDispatchProps {
fetchEntity: FetchEntity
}
//...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With