javascript - How to correctly Type a React Component that is a param of a Function? - Stack Overflow

I have a function, which takes two params: a react ponent, and a string. I am trying to give them corre

I have a function, which takes two params: a react ponent, and a string. I am trying to give them correct typings, however, am confused as to why the following wont work...

The problem is with the typing with GivenComponent in the Function. By giving the param that specific typing of Component<>, the return of the GivenComponent (within the < Query />) errors stating the following:

JSX element type 'GivenComponent' does not have any construct or call signatures. [2604]

However, how would you type that correctly? That param is a React Component, could be both a functional or a class ponent. As seen in the second part of code, the param isn't given as < MyComponent />, it is given as MyComponent - so not the "rendered" jsx? maybe that changes things

Function:

Basically takes a ponent and returns it with a higher order ponent wrapper around it

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;

React Component:

example of how the function above is called with params

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

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



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

const MyComponentWithData = withQueryData(
  MyComponent,
  MyComponentQuery
);

export default MyComponentWithData;

I have a function, which takes two params: a react ponent, and a string. I am trying to give them correct typings, however, am confused as to why the following wont work...

The problem is with the typing with GivenComponent in the Function. By giving the param that specific typing of Component<>, the return of the GivenComponent (within the < Query />) errors stating the following:

JSX element type 'GivenComponent' does not have any construct or call signatures. [2604]

However, how would you type that correctly? That param is a React Component, could be both a functional or a class ponent. As seen in the second part of code, the param isn't given as < MyComponent />, it is given as MyComponent - so not the "rendered" jsx? maybe that changes things

Function:

Basically takes a ponent and returns it with a higher order ponent wrapper around it

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;

React Component:

example of how the function above is called with params

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

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



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

const MyComponentWithData = withQueryData(
  MyComponent,
  MyComponentQuery
);

export default MyComponentWithData;
Share Improve this question edited Mar 20, 2019 at 15:45 user10741122 asked Mar 20, 2019 at 15:42 user10741122user10741122 8911 gold badge16 silver badges29 bronze badges 5
  • Try to use React.ComponentClass | React.FunctionComponent instead of React.Component – Limbo Commented Mar 20, 2019 at 15:44
  • @LevitatorImbalance but the param can be either class ponent or functional. I thought ComponentClass indicates it is a Class Component? – user10741122 Commented Mar 20, 2019 at 15:47
  • Just reviewed a question and edited my ment) – Limbo Commented Mar 20, 2019 at 15:49
  • 1 Or use ComponentType, also don't use : Function that disables inference for withQueryData – Titian Cernicova-Dragomir Commented Mar 20, 2019 at 15:53
  • Also won't you want to forward some props from the wrapper ponent to the wrapped ponent ? Your current versions does nto allow any extra props – Titian Cernicova-Dragomir Commented Mar 20, 2019 at 15:54
Add a ment  | 

2 Answers 2

Reset to default 4

Transforming my ment into an answer.

There are two typings for declared react ponents:

React.ComponentClass - a typing for react ponent that is declared as class:

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

React.FunctionComponent is a typing for function ponent (CO to the rescue! :D)

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

So, if your ponent is one of ComponentClass or FunctionComponent, you can use Union Type and tell the TypeScript about it in this way:

const SomeUnionType: React.ComponentClass | React.FunctionComponent

Thats it! Hope, that helps :)

You need to use ComponentType to represent a ponent type (functional or class, defined in react definitions as type ComponentType<P = {}> = ComponentClass<P> | FunctionComponent<P>;).

Also you might want to allow the HOC to forward properties from the wrapped ponent.

Also remove the Function annotation from withQueryData as that will remove all type safety from 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

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1745090884a4610688.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信