30/11/2019 使用此处的解决方案更新了代码沙箱。
原始问题在28/11/2019问, 我试图学习高级组件,但努力将高级组件连接到redux存储和路由器。希望有人可以帮助解决我与 mapStateToProps 有关的高阶组件类型编译问题。
我正在尝试创建一个更高阶的组件 withErrorListener 。它具有以下功能:
StateProps = { error: IApiFailure[]}
其意图如下使用NewComponent = withErrorListener(withId(BaseComponent))。
NewComponent = withErrorListener(withId(BaseComponent))
,我遇到的问题是,打字稿引发编译错误类型 IApiFailure 不能在找到 ErrorListener 特别类,当它被分配给反应,终极版 连接 功能。IApiFailure是mapStateToProps函数的StateProps返回类型中包含的类型。我可以编译的唯一方法是强制转换为 任何 类型。
HoC通过以下代码段连接到商店。HoC ErrorListener类的完整代码可以在这里找到。我还包括以下错误信息…
随后,我无法将连接的组件连接到withRouter函数。如果我将Hoc ErrorListener转换为connect函数中的任何类型,则编译成功,但OwnProps中的uniqueId属性未定义。这用于过滤错误存储。
/** * 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;
我收到的编译错误如下。我认为打字稿不能识别嵌入型 内 通过mapStateToProps返回的类型,即IApiFailure []类型在无法识别 HocProps 。使用时这不是自动实现的ReturnType<typeof mapStateToProps>吗?
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)
当你使用注射道具mapStateToProps,并dispatchProps在connect您必须减去从这些道具BaseProps使用泛型类型Diff的辅助型。此外,如果要在Hoc组件中使用这些注入的Props,则必须将它们作为Componenttype参数传递。例如React.Component<InjectedProps>。
mapStateToProps
dispatchProps
connect
BaseProps
Diff
Hoc
React.Component<InjectedProps>
这是错误的原因。
因此,在您的示例中,道具是:
type InjectedProps = TStateProps & TDispatchProps; type HocProps = Diff<BaseProps, InjectedProps>; class Hoc extends React.Component<InjectedProps> { ... } const ConnectedHoc = connect< TStateProps, TDispatchProps, HocProps, RootState >( mapStateToProps, dispatchProps )(Hoc);
另外,请检查react-redux-typescript-guide中的相同讨论