styled how component bar reactjs typescript material-ui

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



styled component material ui (5)

Cuando convierto de JSX a TSX y mantenemos algunas bibliotecas como js / jsx y convierto otras a ts / tsx, casi siempre olvido cambiar las declaraciones de importación js / jsx en los archivos TSX / TS de

import * as ComponentName from "ComponentName";

a

import ComponentName from "ComponentName";

Si llama a un antiguo componente de estilo JSX (React.createClass) desde TSX, use

var ComponentName = require("ComponentName")

Escribí un código:

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

Recibo un error:

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

Qué significa eso?


Esta es una confusión entre constructores e instancias .

Recuerde que cuando escribe 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, estamos pasando a Greeter , la función constructora de nuestro componente. Ese es el uso correcto. En el segundo ejemplo, estamos pasando una instancia de Greeter . Eso 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 espera 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 similarmente:

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


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

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


Si está utilizando material-ui , vaya a la definición de tipo del componente, que TypeScript subraya. Lo más probable es que veas algo como esto

export { default } from ''./ComponentName'';

Tiene 2 opciones para resolver el error:

1.Agregue .default cuando use el componente en JSX:

import ComponentName from ''./ComponentName'' const Component = () => <ComponentName.default />

2. Cambie el nombre del componente, que se exporta como "predeterminado", al importar:

import { default as ComponentName } from ''./ComponentName'' const Component = () => <ComponentName />

De esta manera, no necesita especificar .default cada vez que usa el componente.


Si realmente no te interesan los accesorios, el tipo más amplio posible es React.ReactType .

Esto permitiría pasar elementos dom nativos como una cadena. React.ReactType cubre todo esto:

renderGreeting(''button''); renderGreeting(() => ''Hello, World!''); renderGreeting(class Foo extends React.Component { render() { return ''Hello, World!'' } });