Reputation: 3022
I am a new react/redux user struggling to get a higher order component connected to redux store through connect function. My code is as follows...
Redux state and dispatch props
export const mapStateToProps = (
state: RootState,
ownProps: ApiErrorComponentInjectedProps,
): StateProps => ({
error: filterErrors(state.errors as StateProps, ownProps),
});
export const dispatchProps = {
clearError: clearErrorAction,
};
Higher Order Component
import * as redux from './reduxConnect';
type ApiErrorDispatchProps = typeof redux.dispatchProps;
type ApiErrorStateProps = ReturnType<typeof redux.mapStateToProps>;
export const withReduxErrorListener = <
BaseProps extends ApiErrorComponentInjectedProps
>(
ChildComponent: ComponentType<BaseProps>,
) => {
/**
* @typename HocProps Base properties passed into component, ReturnType<mapStateToProps>, typeof dispatchProps, RouteComponentProps
*/
type HocProps = BaseProps &
ApiErrorStateProps &
ApiErrorDispatchProps &
RouteComponentProps;
/**
* Higher Order Component (HoC)
*/
class ApiErrorListener extends React.Component<HocProps, {}> {
/**
* Pass properties to base constructor
* @param props Initialisation properties
*/
constructor(props: HocProps) {
super(props);
}
...
}
const ConnectedHoc = connect<
ApiErrorStateProps,
ApiErrorDispatchProps,
HocProps,
RootState
>(
mapStateToProps,
dispatchProps,
)(ApiErrorListener); // this is causing a compilation error
return ConnectedHoc;
};
When I try to hook up the connect function to the higher order component I receive the following error informing that types of parameters 'props' and 'props' are incompatible. I think it is related to dispatch properties?? Has anyone experienced anything similar?
TS2345: Argument of type 'typeof ApiErrorListener' is not assignable to parameter of type 'ComponentType<Matching<StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; }, HocProps>>'.
Type 'typeof ApiErrorListener' is not assignable to type 'ComponentClass<Matching<StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; }, HocProps>, any>'.
Types of parameters 'props' and 'props' are incompatible.
Type 'Matching<StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; }, HocProps>' is not assignable to type 'HocProps'.
Type 'Matching<StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; }, HocProps>' is not assignable to type 'BaseProps'.
'Matching<StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; }, HocProps>' is assignable to the constraint of type 'BaseProps', but 'BaseProps' could be instantiated with a different subtype of constraint 'ApiErrorComponentInjectedProps'.
Type 'P extends "error" | "clearError" ? (StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<...>; })[P] extends HocProps[P] ? HocProps[P] : (StateProps & { ...; })[P] : HocProps[P]' is not assignable to type 'BaseProps[P]'.
Type '((StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; })[P] extends HocProps[P] ? HocProps[P] : (StateProps & { ...; })[P]) | HocProps[P]' is not assignable to type 'BaseProps[P]'.
Type '(StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; })[P] extends HocProps[P] ? HocProps[P] : (StateProps & { ...; })[P]' is not assignable to type 'BaseProps[P]'.
Type '(StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; })[P] | HocProps[P]' is not assignable to type 'BaseProps[P]'.
Type '(StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; })[P]' is not assignable to type 'BaseProps[P]'.
Type 'StateProps & { clearError: (raisingAction: string, sourceComponent: string, history?: History<any> | undefined, navigateTo?: string | undefined) => PayloadAction<constants.CLEAR_API_ERROR, ClearError>; }' is not assignable to type 'BaseProps'.
Type 'HocProps["history"] | HocProps["location"] | HocProps["match"] | HocProps["staticContext"] | (IApiFailure[] extends HocProps["error"] ? HocProps["error"] : IApiFailure[]) | ((raisingAction: string, sourceComponent: string, history?: History<...> | undefined, navigateTo?: string | undefined) => PayloadAction<...> ext...' is not assignable to type 'BaseProps[P]'.
Type 'BaseProps["history"] & History<any>' is not assignable to type 'BaseProps[P]'.
Upvotes: 2
Views: 1254
Reputation: 3022
The issue was incorrect typing of the connect function in the HoC.
After some refactoring and a secondary question here managed to solve the issue with some help from the author of react-redux-typescript-guide](https://github.com/piotrwitek/react-redux-typescript-guide) managed to get it working.
The HoC was refactored to follow the pattern suggested in the react-redux-typescript-guide.
I created a codesandbox in the event that others encounter a similar issue.
Upvotes: 2