使用高阶组件的mapState函数遇到编译错误,该函数返回对象内的对象

时间:2019-11-28 12:01:44

标签: reactjs typescript redux react-redux

2019/11/30 使用解决方案here更新了代码沙箱。

原始问题在2019年11月28日问到 我正在尝试学习高阶组件,但努力将高阶组件连接到redux存储和路由器。希望有人可以帮助解决与 mapStateToProps 相关的高阶组件类型编译问题。

我正在尝试创建更高阶的组件withErrorListener。它具有以下功能:

  1. withErrorListener 包装具有 uniqueId属性的基本组件。 uniqueId属性由另一个高阶组件withId创建。
  2. withErrorListener 返回一个包装类组件,该组件侦听redux存储并过滤针对该基本组件通知的错误。如果没有错误要显示,它将渲染基础组件。我正在使用 mapStateToProps(state,ownProps)=> StateProps (其中StateProps = { error: IApiFailure[]}
  3. )过滤redux状态下的错误
  4. wthErrorListener 呈现错误,并通过在错误呈现页面上单击“主页”按钮来卸载该组件时,调度_clear_error_操作。这意味着高阶组件还需要 RouterComponentProps 依赖项。

其用途如下NewComponent = withErrorListener(withId(BaseComponent))

我遇到的问题是Typescript引发了将 IApiFailure 类型分配给react-redux的 ErrorListener HoC类中找不到的编译错误 connect 功能。 IApiFailure是mapStateToProps函数的StateProps返回类型中包含的类型。我可以编译的唯一方法是强制转换为 any 类型。

HoC通过以下代码片段连接到商店。您可以在here中找到HoC ErrorListener类的完整代码。我还包括以下错误信息...

因此,我无法将连接的组件连接到withRouter函数。 如果我将Hoc ErrorListener强制转换为connect函数中的任何类型,则编译成功,但OwnProps is undefined中的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返回的内部类型,即 HocProps 无法识别IApiFailure []类型。使用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)

1 个答案:

答案 0 :(得分:0)

mapStateToProps中使用dispatchPropsconnect注入道具时,必须使用{{1 }}辅助类型。 此外,如果要在BaseProps组件中使用这些注入的Props,则必须将它们作为Component type参数传递。例如Diff

这是导致错误的原因。

所以在您的示例中道具是:

Hoc

另外,请检查react-redux-typescript-guide

中的相同讨论