React hoc 一般错误 - 可以使用不同的约束子类型实例化 'InjectedProps'

React hoc Generic error - could be instantiated with a different subtype of constraint 'InjectedProps'

我已将我的示例精简到最低限度以理解问题:

示例代码 - Hoc.tsx

import React, { FC, ComponentType } from 'react';
import { connect } from 'react-redux';

interface ReduxProps {
  param: string;
}

interface InjectedProps {
  str: string;
}

const withWrapper = <P extends InjectedProps>(Comp: ComponentType<P>) => {
  const Wrapper: FC<ReduxProps> = ({ param }) => {
    // do sometthing with param
    // inject property
    const str = 'hello';
    return <Comp str={str} />;
  };
  Wrapper.displayName = 'Wrapper';

  // removed actual state to show example to test in typescript playground
  const mapStateToProps = () => ({
    param: 'some param'
  });

  const connector = connect(mapStateToProps);
  return connector(Wrapper);
};

export default withWrapper;

在 typescript playground 中我得到这个错误:

错误

Type '{ str: string; }' is not assignable to type 'P'. '{ str: string; }' is assignable to the constraint of type 'P', but 'P' could be instantiated with a different subtype of constraint 'InjectedProps'

如何将道具注入我的高阶组件并保留提供的泛型?

这有点笨拙,但找到了解决方案

import React, { FC, ComponentType } from 'react';
import { connect } from 'react-redux';

interface ReduxProps {
  param: string;
}

interface InjectedProps {
  str: string;
}

const withWrapper = <P extends {}>(Comp: ComponentType<P | InjectedProps>) => {
  const Wrapper: FC<ReduxProps> = ({ param }) => {
    // do sometthing with param
    // inject property
    const str = 'hello';
    return <Comp str={str} />;
  };
  Wrapper.displayName = 'Wrapper';

  // removed actual state to show example to test in typescript playground
  const mapStateToProps = () => ({
    param: 'some param'
  });

  const connector = connect(mapStateToProps);
  return connector(Wrapper);
};

export default withWrapper;

interface Props {
  something: string;
}
const ConsumeWith: FC<Props | InjectedProps> = props => {
  const str = (props as InjectedProps).str;
  const something = (props as Props).something;

  return (
    <div>
      {str}{something}
    </div>
  );
};

const Final = withWrapper<Props>(ConsumeWith);