繁体   English   中英

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

[英]How to correctly Type a React Component that is a param of a Function?

我有一个函数,需要两个参数:react组件和一个字符串。 我试图给他们正确的打字,但是,为什么下面的工作不正确...

问题在于在Function中使用GivenComponent进行键入。 通过为参数指定Component <>的特定类型,GiveComponent的返回(在<Query />内)错误说明以下内容:

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

但是,您如何正确键入呢? 该参数是一个React组件,既可以是功能组件,也可以是类组件。 如在代码的第二部分中看到的那样,该参数没有以<MyComponent />的形式给出,而是以MyComponent的形式给出-因此,不是“渲染的” jsx? 也许那改变了事情

功能:

基本上获取一个组件,并返回一个带有高阶组件包装的组件

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;

反应组件:

如何使用params调用上述函数的示例

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

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



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

const MyComponentWithData = withQueryData(
  MyComponent,
  MyComponentQuery
);

export default MyComponentWithData;

将我的评论转化为答案。

声明的react组件有两种类型:

React.ComponentClass - React.ComponentClass组件的类型,声明为class:

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

React.FunctionComponent是功能组件的类型(CO来解救!:D)

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

因此,如果您的组件是ComponentClassFunctionComponent ,则可以使用Union Type并以这种方式告知TypeScript:

const SomeUnionType: React.ComponentClass | React.FunctionComponent

而已! 希望有帮助:)

您需要使用ComponentType来表示组件类型(功能或类,在React定义中定义为type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>; )。

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

同时删除该Function从注释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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM