我有一个函数,它带有两个参数:react组件和一个字符串。我试图给他们正确的输入方式,但是,为什么下面的方法行不通呢?
问题在于在函数中使用GivenComponent进行键入。通过为参数指定Component <>的特定类型,GiveComponent返回(在
JSX元素类型'GivenComponent'没有任何构造或调用签名。 [2604]
但是,您如何正确键入呢?该参数是一个React组件,既可以是功能组件,也可以是类组件。如在代码的第二部分中看到的那样,该参数没有以
基本上获取一个组件,并返回一个带有高阶组件包装的组件
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;
答案 0 :(得分:1)
将我的评论转化为答案。
已声明的react组件有两种类型:
React.ComponentClass
-声明为class的react组件的输入:
class SomeComponent extends React.Component {...} // this is React.ComponentClass
React.FunctionComponent
是功能组件的输入(用于救援的CO!:D)
const MyFunctionComponent: React.FunctionComponent = props => "something"
因此,如果您的组件是ComponentClass
或FunctionComponent
之一,则可以使用Union Type并以这种方式告知TypeScript:
const SomeUnionType: React.ComponentClass | React.FunctionComponent
就这样!希望有帮助:)
答案 1 :(得分:1)
您需要使用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