我写了一些代码:

function renderGreeting(Elem: React.Component<any, any>) {
    return <span>Hello, <Elem />!</span>;
}

我得到一个错误:

JSX元素类型Elem没有任何构造或调用签名

这是什么意思?


当前回答

如果你想把一个组件类作为参数(而不是一个实例),使用React。ComponentClass:

function renderGreeting(Elem: React.ComponentClass<any>) {
    return <span>Hello, <Elem />!</span>;
}

其他回答

就我而言,我使用的是React。ReactNode作为功能组件的类型,而不是React。FC型。

准确地说,在这个组件中:

export const PropertiesList: React。FC = (props: any) => { Const列表:string[] = [ 《后果:Phasellus sollicitudin》, 《后果:Phasellus sollicitudin》, “……” ] 回报( <列表 header={<ListHeader header= "Properties List" />} 数据源={}列表 renderItem={(listItem, index) => <列表。项目键={index}> {listItem} </List. index . > {listtitem}项> } /> ) }

这是构造函数和实例之间的混淆。

记住,当你在React中编写一个组件时:

class Greeter extends React.Component<any, any> {
    render() {
        return <div>Hello, {this.props.whoToGreet}</div>;
    }
}

你可以这样用:

return <Greeter whoToGreet='world' />;

你不能这样用:

let Greet = new Greeter();
return <Greet whoToGreet='world' />;

在第一个例子中,我们传递了组件的构造函数Greeter。这是正确的用法。在第二个例子中,我们传递了一个Greeter实例。这是不正确的,将在运行时失败,并出现类似“对象不是函数”的错误。


这段代码的问题

function renderGreeting(Elem: React.Component<any, any>) {
    return <span>Hello, <Elem />!</span>;
}

它期待一个React.Component的实例。你需要的是一个带有React构造函数的函数。组件:

function renderGreeting(Elem: new() => React.Component<any, any>) {
    return <span>Hello, <Elem />!</span>;
}

或类似的:

function renderGreeting(Elem: typeof React.Component) {
    return <span>Hello, <Elem />!</span>;
}

如果你将功能组件作为道具传递给另一个组件,请使用以下命令:

import React from 'react';

type RenderGreetingProps = {
  element: React.FunctionComponent<any>
};

function RenderGreeting(props: RenderGreetingProps) {
  const {element: Element} = props;

  return <span>Hello, <Element />!</span>;
}

如果你想把一个组件类作为参数(而不是一个实例),使用React。ComponentClass:

function renderGreeting(Elem: React.ComponentClass<any>) {
    return <span>Hello, <Elem />!</span>;
}

看起来现在有一个特殊的新TypeScript类型来解决这个问题:JSXElementConstructor。如果你让某人将构造函数传递给一个未知的ReactElement,而不是该ReactElement的实例,这是传递的正确类型。

const renderGreeting = (Elem: JSXElementConstructor<any>) => {
    return <span>Hello, <Elem />!</span>;
}

这等价于上面选择的正确答案,因为:在JSX中使用<Elem />(也就是用尖括号将大写变量括起来)等效于使用new关键字调用JSX元素的构造函数。