【问题标题】:How to solve Redux React Typescript Higher Order Component (Hoc) compile error "props and props" are incompatible如何解决 Redux React Typescript Higher Order Component (Hoc) 编译错误“props and props” is incompatible
【发布时间】:2020-03-18 17:47:32
【问题描述】:

我是一个新的 react/redux 用户,正在努力通过 connect 函数将高阶组件连接到 redux 存储。我的代码如下...

Redux 状态和调度道具

export const mapStateToProps = (
  state: RootState,
  ownProps: ApiErrorComponentInjectedProps,
): StateProps => ({
  error: filterErrors(state.errors as StateProps, ownProps),
});

export const dispatchProps = {
  clearError: clearErrorAction,
};

高阶组件

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;
};

当我尝试将连接函数连接到高阶组件时,我收到以下错误,通知参数“props”和“props”的类型不兼容。我认为它与调度属性有关?有没有人经历过类似的事情?

  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]'.

【问题讨论】:

    标签: reactjs typescript redux higher-order-components


    【解决方案1】:

    问题是在 HoC 中连接函数的输入不正确。

    经过一些重构和一个次要问题 here 在 react-redux-typescript-guide 的作者的帮助下设法解决了这个问题](https://github.com/piotrwitek/react-redux-typescript-guide) 设法让它工作。

    HoC 被重构为遵循 react-redux-typescript-guide 中建议的 pattern

    我创建了一个codesandbox,以防其他人遇到类似问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2021-08-18
      • 2020-07-06
      • 2020-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-01
      • 2019-01-07
      相关资源
      最近更新 更多