30/11/2019 使用此处的解决方案更新了代码沙箱。
2019 年 11 月 28 日提出的原始问题 我正在尝试学习高阶组件,但很难将高阶组件连接到 redux 存储和路由器。希望有人可以帮助我解决与mapStateToProps相关的高阶组件类型编译问题。
我正在尝试创建一个更高阶的组件withErrorListener。它具有以下特点:
- withErrorListener包装了一个具有uniqueId属性的基本组件。uniqueId 属性由另一个高阶组件withId 创建。
- withErrorListener返回一个包装类组件,该组件侦听 redux 存储并过滤为该基本组件通知的错误。如果没有要显示的错误,它将呈现基本组件。我正在使用mapStateToProps(state, ownProps) => StateProps过滤 redux 状态中的错误,其中
StateProps = { error: IApiFailure[]} - 当通过单击错误呈现页面上的主页按钮卸载组件时,wthErrorListener呈现错误并调度 _clear_error_ 操作。这意味着高阶组件也需要RouterComponentProps依赖。
它的用途如下NewComponent = withErrorListener(withId(BaseComponent))。
我遇到的问题是 Typescript 会引发编译错误,即在将其分配给 react-redux连接函数时,在ErrorListener HoC 类中找不到类型IApiFailure。IApiFailure 是一种包含在 mapStateToProps 函数的 StateProps 返回类型中的类型。我可以让它编译的唯一方法是强制转换为any类型。
HoC 通过下面的代码片段连接到商店。可以在此处找到 HoC ErrorListener 类的完整代码。我还包括下面的错误信息......
随后,我无法将连接的组件连接到 withRouter 函数。如果我将 Hoc ErrorListener 转换为连接函数中的任何类型,则编译成功,但OwnProps中的uniqueId属性是 undefined。这用于过滤错误存储。
/**
* Redux properties
*/
type StateProps = {
error: FailureNotify[];
};
/**
* Function to return subset of store state that filters errors for the wrapped component via uniqueId property
* @param state The root state
* @param ownProps Properties passed to wrapped component according to `https://react-redux.js.org/next/using-react-redux/connect-mapstate#ownprops-optional`
* @returns StateProps type that contains a list of filtered errors of type FailureNotify.
*/
const mapStateToProps = (
state: RootState,
ownProps: HocProps
): StateProps => {
console.log(`withErrorListener mapStateToProps => ${ownProps.uniqueId}`);
return {
error: filterErrors(state.errors, ownProps)
};
};
const dispatchProps = {
clearError: clearErrorAction
};
/**
* Type declarations
*/
type TStateProps = ReturnType<typeof mapStateToProps>;
type TDispatchProps = typeof dispatchProps;
type HocProps = BaseProps & TStateProps & TDispatchProps;
const ConnectedHoc = connect<
TStateProps,
TDispatchProps,
ExpectedProps,
RootState
>(
mapStateToProps,
dispatchProps
)(ErrorListener); // this raises the error below...unless I cast it as any
return ConnectedHoc;
// const RouteHoc = withRouter(ConnectedHoc);
// return RouteHoc;
我收到的编译错误如下。我认为typescript不能识别嵌入型内通过mapStateToProps返回的类型,即IApiFailure []类型在无法识别HocProps。这不是在使用时自动实现的ReturnType<typeof mapStateToProps>吗?
Argument of type 'typeof ErrorListener' is not assignable to parameter of type 'ComponentType<Matching<StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; }, HocProps>>'.
Type 'typeof ErrorListener' is not assignable to type 'ComponentClass<Matching<StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; }, HocProps>, any>'.
Types of parameters 'props' and 'props' are incompatible.
Type 'Matching<StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; }, HocProps>' is not assignable to type 'Readonly<HocProps>'.
Type 'P extends "error" | "clearError" ? (StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; })[P] extends HocProps[P] ? HocProps[P] : (StateProps & { ...; })[P] : HocProps[P]' is not assignable to type 'HocProps[P]'.
Type 'HocProps[P] | ((StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; })[P] extends HocProps[P] ? HocProps[P] : (StateProps & { ...; })[P])' is not assignable to type 'HocProps[P]'.
Type '(StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; })[P] extends HocProps[P] ? HocProps[P] : (StateProps & { ...; })[P]' is not assignable to type 'HocProps[P]'.
Type '(StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; })[P] | HocProps[P]' is not assignable to type 'HocProps[P]'.
Type '(StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; })[P]' is not assignable to type 'HocProps[P]'.
Type 'StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; }' is not assignable to type 'HocProps'.
Type 'StateProps & { clearError: (fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<constants.CLEAR_ERROR, ClearError>; }' is not assignable to type 'BaseProps'.
Type '(FailureNotify[] extends HocProps["error"] ? HocProps["error"] : FailureNotify[]) | ((fromAction: string, fromComponent: string, history?: History<any>, navigateTo?: string) => PayloadAction<...> extends HocProps["clearError"] ? HocProps["clearError"] : (fromAction: string, fromComponent: string, history?: History<....' is not assignable to type 'HocProps[P]'.
Type 'FailureNotify[] extends HocProps["error"] ? HocProps["error"] : FailureNotify[]' is not assignable to type 'HocProps[P]'.
Type 'FailureNotify[] | HocProps["error"]' is not assignable to type 'HocProps[P]'.
Type 'FailureNotify[]' is not assignable to type 'HocProps[P]'.ts(2345)