¿Qué significa el error "El tipo de elemento JSX '...' no tiene ninguna firma de construcción o llamada"?

Resuelto Ryan Cavanaugh asked hace 9 años • 21 respuestas

Escribí un código:

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

Recibo un error:

El tipo de elemento JSX Elemno tiene ninguna construcción o firma de llamada

¿Qué significa?

Ryan Cavanaugh avatar Aug 05 '15 00:08 Ryan Cavanaugh
Aceptado

Ésta es una confusión entre constructores e instancias .

Recuerda que cuando escribes un componente en React:

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

Lo usas de esta manera:

return <Greeter whoToGreet='world' />;

No lo usas de esta manera:

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

En el primer ejemplo, pasamos Greeterla función constructora de nuestro componente. Ese es el uso correcto. En el segundo ejemplo, pasamos una instancia de Greeter. Esto es incorrecto y fallará en tiempo de ejecución con un error como "El objeto no es una función".


El problema con este código.

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

es que está esperando una instancia de React.Component. Lo que quieres es una función que tome un constructor para React.Component:

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

o similar:

function renderGreeting(Elem: typeof React.Component) {
    return <span>Hello, <Elem />!</span>;
}
Ryan Cavanaugh avatar Aug 04 '2015 17:08 Ryan Cavanaugh

Si desea tomar una clase de componente como parámetro (en lugar de una instancia), use React.ComponentClass:

function renderGreeting(Elem: React.ComponentClass<any>) {
    return <span>Hello, <Elem />!</span>;
}
Luke avatar Jul 03 '2017 23:07 Luke

Lo siguiente funcionó para mí: https://github.com/microsoft/TypeScript/issues/28631#issuecomment -472606019 Lo soluciono haciendo algo como esto:

const Component = (isFoo ? FooComponent : BarComponent) as React.ElementType
Warao avatar Feb 20 '2020 15:02 Warao