使用返回对象内的对象的高阶组件的 mapState 函数遇到编译错误 [英] Experiencing compile error with a higher order component's mapState function that returns an object within an object

查看:34
本文介绍了使用返回对象内的对象的高阶组件的 mapState 函数遇到编译错误的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

30/11/2019 Updated the code sandbox with the solution here.

原始问题于 28/11/2019 提出我正在尝试学习高阶组件,但很难将高阶组件连接到 redux 存储和路由器.希望有人能帮助我解决与 mapStateToProps 相关的高阶组件类型编译问题.

Original Question asked on 28/11/2019 I am trying to learn Higher Order Components but struggling to get a Higher Order Component connected to the redux store and router. Hoping that someone can help with a Higher Order Component type compilation problem I am struggling with relating to mapStateToProps.

我正在尝试创建一个更高阶的组件,withErrorListener.它具有以下特点:

I am trying to create a higher order component, withErrorListener. It has the following features:

  1. withErrorListener 包装了一个具有 uniqueId 属性 的基础组件.uniqueId 属性由另一个高阶组件创建,withId.
  2. withErrorListener 返回一个包装类组件,该组件侦听 redux 存储并过滤为该基本组件通知的错误.如果没有要显示的错误,它将呈现基本组件.我正在使用 mapStateToProps(state, ownProps) => StateProps 过滤 redux 状态中的错误,其中 StateProps = { error: IApiFailure[]}
  3. wthErrorListener 呈现错误并在通过单击错误呈现页面上的主页按钮卸载组件时调度 _clear_error_ 操作.这意味着高阶组件也需要 RouterComponentProps 依赖项.
  1. withErrorListener wraps a base component that has the uniqueId property. The uniqueId property is created by another Higher Order Component, withId.
  2. withErrorListener returns a wrapper class component that listens on the redux store and filters errors notified for that the base component. If there are no errors to display it renders the base component. I am filtering errors in redux state using mapStateToProps(state, ownProps) => StateProps, where StateProps = { error: IApiFailure[]}
  3. wthErrorListener renders the errors and dispatches a _clear_error_ action when the component is unmounted by clicking home button on error rendered page. This means that the higher order component also requires RouterComponentProps dependency.

它的用途如下NewComponent = withErrorListener(withId(BaseComponent)).

我遇到的问题是 Typescript 引发了编译错误,即类型 IApiFailure 在分配给 react-redux 时无法在 ErrorListener HoC 类中找到连接功能.IApiFailure 是一种包含在 mapStateToProps 函数的 StateProps 返回类型中的类型.我可以让它编译的唯一方法是强制转换为 any 类型.

The problem that I am encountering is that Typescript raises the compile error that type IApiFailure cannot be found in the ErrorListener HoC class when it is assigned to the react-redux connect function. IApiFailure is a type contained within the StateProps return type for the mapStateToProps function. The only way that I can get it to compile is to cast to the any type.

HoC 通过以下代码片段连接到商店.HoC ErrorListener 类的完整代码可以在 此处.我还包括下面的错误信息...

The HoC is connected to the store with the following code snippet below. The full code for the HoC ErrorListener class can be found here. I have also included the error information below ...

随后,我无法将连接的组件连接到 withRouter 函数.如果我将 Hoc ErrorListener 转换为连接函数中的任何类型,则编译成功,但 OwnProps 未定义.这用于过滤错误存储.

Subsequently, I cannot connect the connected component to the withRouter function. If I cast the Hoc ErrorListener to any type in the connect function, then compilation succeeds but the uniqueId property in OwnProps is undefined. This is used to filter the error store.

  /**
   * 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 无法识别嵌入 in 由 mapStateToProps 返回的类型的类型,即 IApiFailure[] 类型在 HocProps 中无法识别.这不是在使用ReturnType时自动实现的吗?

The compile error that I receive is below. I think typescript is not recognising the type embedded within the type returned by mapStateToProps, i.e. IApiFailure[] type is unrecognised in HocProps. Is this not automatically achieved when using 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)

推荐答案

当您在 connect 中使用 mapStateToPropsdispatchProps 注入 Props 时code> 你必须使用 Diff 辅助类型从 BaseProps 泛型类型中减去这些道具.此外,如果您想在 Hoc 组件中使用这些注入的 Props,您必须将它们作为 Component 类型参数传递.例如React.Component.

When you're injecting Props by using mapStateToProps and dispatchProps in a connect you have to subtract these props from the BaseProps generic type by using the Diff helper type. Moreover, if you want to use these injected Props in the Hoc component you have to pass them as the Component type argument. e.g. React.Component<InjectedProps>.

这是错误的原因.

因此在您的示例中,道具是:

So in your example props are:

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- 中的相同讨论打字稿指南

这篇关于使用返回对象内的对象的高阶组件的 mapState 函数遇到编译错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆