代码之家  ›  专栏  ›  技术社区  ›  Grant Birchmeier

如何允许组件接受FunctionComponent或Component参数

  •  0
  • Grant Birchmeier  · 技术社区  · 5 年前

    我用的是Typescript和ReactJS,我是个书呆子。我正在尝试做一些我认为应该简单的事情,但是打字脚本正在阻碍我。

    我有两个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>(道具:只读<P>):组件<P、 S,SS>'。

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

    但我不知道是什么 应该 是有什么方法可以定义吗 PublicRouteWrapper 所以这两个页面都可以作为参数使用?

    0 回复  |  直到 5 年前
        1
  •  2
  •   Oblosys    5 年前

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

    这个 IPublicRouteWrapperProps 接口可以写成:

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