类withRouter高阶组件如何用Typescript完善类型校验?

类withRouter高阶组件如何用Typescript完善类型校验?

举个例子(实现自动给低阶组件传递参数param1和param2)

import React from 'react';
import ReactDOM from 'react-dom';
import hoistStatics from 'hoist-non-react-statics';

function withAny(Component) {
  const displayName = `withAny(${Component.displayName || Component.name})`;
  const C = props => {
    const { ...remainingProps } = props;
    const newProps = {
      param1: 1,
      param2: 2,
    };

    return <Component {...remainingProps} {...newProps} />;
  };

  C.displayName = displayName;

  return hoistStatics(C, Component);
}

const BaseComponent = props => {
  return (
    <ul>
      <li>{props.param1}</li>
      <li>{props.param2}</li>
      <li>{props.name}</li>
      <li>{props.age}</li>
    </ul>
  );
};
const WrappedComponent = withAny(BaseComponent);

ReactDOM.render(
  <WrappedComponent name="jay" age={40} />,
  document.getElementById('root'),
);

尝试一

import React from 'react';
import ReactDOM from 'react-dom';
import hoistStatics from 'hoist-non-react-statics';

interface WrappedComponentProps {
  param1: number;
  param2: number;
}
interface BaseComponentProps {
  name: string;
  age: number;
}
function withAny<P extends WrappedComponentProps>(
  Component: React.ComponentType<P>,
): React.ComponentType<Omit<P, keyof WrappedComponentProps>> {
  const displayName = `withAny(${Component.displayName || Component.name})`;
  const C: React.FC = props => {
    const { ...remainingProps } = props;
    const newProps = {
      param1: 1,
      param2: 2,
    };

    return <Component {...remainingProps} {...newProps} />; // Error: but 'P' could be instantiated with a different subtype of constraint 'WrappedComponentProps'
  };

  C.displayName = displayName;

  return hoistStatics(C, Component);
}

const BaseComponent: React.FC<WrappedComponentProps & BaseComponentProps> = props => {
  return (
    <ul>
      <li>{props.param1}</li>
      <li>{props.param2}</li>
      <li>{props.name}</li>
      <li>{props.age}</li>
    </ul>
  );
};
const WrappedComponent = withAny(BaseComponent);

ReactDOM.render(
  <WrappedComponent name="jay" age={40} />,
  document.getElementById('root') as HTMLElement,
);

我这个尝试一感觉和成功差了一步,不知道怎么修正了。。。

阅读 2.7k
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题