簡體   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