首页 > 解决方案 > 如何允许组件采用 FunctionComponent 或组件的参数

问题描述

我正在使用 Typescript 和 ReactJS,我是个菜鸟。我正在尝试做一些我认为应该很简单的事情,但 Typescript 正在妨碍我。

我有两个 React 页面组件定义如下:

const HomePage: React.FunctionComponent = () => (
  // stateless component, just JSX and no logic
)


class ReceiptPage extends React.Component<IReceiptPageProps> {
  // has logic and state, defines render()
}

另一个组件应该能够将这两个都作为参数:

export interface IPublicRouteWrapperProps extends IPublicRouteProps {
  component: typeof Component;   // <---- Works for ReceiptPage, but not HomePage
  layout: typeof Layout;
}

const PublicRouteWrapper: React.FunctionComponent<IPublicRouteWrapperProps> = ({
  component: Component,
  layout: Layout,
  ...rest
}) => (
  <PublicRoute
    {...rest}
    render={props => (
      <Layout>
        <Component {...props} />
      </Layout>
    )}
  />
);

这在我传入 ReceiptPage 组件时有效,但在我传入 HomePage 组件时无效:

    <PublicRouteWrapper
      title="blah"
      path={`${match.url}`}
      component={HomePage} // <-- error here, but works fine with ReceiptPage
      exact={true}
    />

错误是:

类型“FunctionComponent<{}>”不可分配给类型“typeof Component”。
类型“FunctionComponent<{}>”不匹配签名“new <P = {}, S = {}, SS = any>(props: Readonly<P>): Component<P, S, SS>”。

这是有道理的,因为 HomePage 不是那种类型。

但我无法弄清楚它应该是什么。有没有一种方法可以定义PublicRouteWrapper,以便任一页面都可以用作参数?

标签: reactjstypescript

解决方案


我相信您正在寻找React.ComponentType,它是ComponentClass(表示类组件的接口)和FunctionComponent. 该类型可以使用 props 类型进行参数化,但您可以选择any允许所有组件使用任何 props。稍后,您可以通过指定实际类型来提高类型安全性。

IPublicRouteWrapperProps接口可以写成:

export interface IPublicRouteWrapperProps extends IPublicRouteProps {
  component: React.ComponentType<any>;   // <----  Works for both ReceiptPage & HomePage
  layout: typeof Layout;
}

推荐阅读