提问者:小点点

如何正确键入作为函数参数的React组件?


我有一个函数,它需要两个参数:一个反应组件和一个字符串。我试图给他们正确的打字,然而,我困惑于为什么以下不会工作...

问题在于在函数中键入GivenComponent。通过给参数指定组件的特定类型

JSX元素类型“GivenComponent”没有任何构造或调用签名。[2604]

然而,你如何正确地键入?该参数是React Component,既可以是函数组件,也可以是类组件。如代码的第二部分所示,参数不是作为

基本上是获取一个组件,并在其周围返回一个高阶组件包装器

import React, { Component } from "react";

const withQueryData: Function = (
  GivenComponent: Component<{ data: {} }, any>,
  query: string
) => () => (

  <Query query={gql(query)}>
    {({ loading, error, data }) => {
      if (loading) return <p>Loading...</p>;
      if (error) return <p>Error! {error.message}</p>;

      return <GivenComponent data={data} />;
    }}
  </Query>
);

export default withQueryData;

如何用参数调用上面的函数的示例

class MyComponent extends Component<...removed...> {

  render() {
    return (
      <div>...</div>
    );
  }
}



const MyComponentQuery = `query goes here...`;

const MyComponentWithData = withQueryData(
  MyComponent,
  MyComponentQuery
);

export default MyComponentWithData;

共2个答案

匿名用户

将我的评论转化为答案。

声明的反应成分有两种类型:

反应。ComponentClass-声明为class的react组件的类型:

class SomeComponent extends React.Component {...} // this is React.ComponentClass

反应。FunctionComponent是功能组件的一种类型(CO to the rescue!:D)

const MyFunctionComponent: React.FunctionComponent = props => "something"

因此,如果您的组件是ComponentClassFunctionComponent中的一个组件,则可以使用Union Type并通过以下方式告知类型脚本:

const SomeUnionType: React.ComponentClass | React.FunctionComponent

就是它!希望,这有帮助:)

匿名用户

您需要使用ComponentType来表示组件类型(函数或类,在react定义中定义为type ComponentType

另外,您可能希望允许HOC从包装的组件转发属性。

同时从withQueryData中删除函数注释,因为这将从withQueryData中删除所有类型安全性。

import { Component, ComponentType } from "react";
type Omit<T, K extends keyof T> = Pick<T, Exclude<keyof T, K>>
const withQueryData = <P extends { data: {} }>(
  GivenComponent: ComponentType<P>,
  query: string
) => (p: Omit<P, 'data'>) => (

  <Query query={gql(query)}>
    {({ loading, error, data }) => {
      if (loading) return <p>Loading...</p>;
      if (error) return <p>Error! {error.message}</p>;

      return <GivenComponent data={data} {...p as any} />;
    }}
  </Query>
);

class MyComponent extends Component<{ data: {}, otherProp: string }> {

  render() {
    return (
      <div>...</div>
    );
  }
}



const MyComponentQuery = `query goes here...`;

const MyComponentWithData = withQueryData(
  MyComponent,
  MyComponentQuery
);

export default MyComponentWithData;

let o = () => <MyComponentWithData otherProp="" ></MyComponentWithData>  // otherProp required, data provided bu the HOC