J'ai écrit du code:
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
J'obtiens une erreur:
Le type d'élément JSX
Elemn'a aucune construction ni signature d'appel
Qu'est-ce que ça veut dire?
J'ai écrit du code:
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
J'obtiens une erreur:
Le type d'élément JSX
Elemn'a aucune construction ni signature d'appel
Qu'est-ce que ça veut dire?
Réponses:
Il s'agit d'une confusion entre les constructeurs et les instances .
N'oubliez pas que lorsque vous écrivez un composant dans React:
class Greeter extends React.Component<any, any> {
render() {
return <div>Hello, {this.props.whoToGreet}</div>;
}
}
Vous l'utilisez de cette façon:
return <Greeter whoToGreet='world' />;
Vous ne l' utilisez pas de cette façon:
let Greet = new Greeter();
return <Greet whoToGreet='world' />;
Dans le premier exemple, nous transmettons Greeterla fonction constructeur de notre composant. C'est l'usage correct. Dans le deuxième exemple, nous transmettons une instance de Greeter. C'est incorrect et échouera au moment de l'exécution avec une erreur du type "L'objet n'est pas une fonction".
Le problème avec ce code
function renderGreeting(Elem: React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
est qu'il attend une instance de React.Component. Ce que vous voulez une fonction qui prend un constructeur pour React.Component:
function renderGreeting(Elem: new() => React.Component<any, any>) {
return <span>Hello, <Elem />!</span>;
}
ou de manière similaire:
function renderGreeting(Elem: typeof React.Component) {
return <span>Hello, <Elem />!</span>;
}
function renderGreeting(Elem: typeof React.Component)dans ES6?
function renderGreeting (Elem: new() => React.SFC<any>){...}si oui, pourquoi déclarons-nous le type de SFC comme ceci:, const Hello:React.SFC<any> = (props) => <div>Hello World</div>et non:const Hello: new() =>React.SFC<any> = (props) => <div>Hello World</div>
export const BackNavigationTextWrapper = (WrappedComponent: typeof React.Component) => { const BackNavigationTextWrappedComponent = (props, { commonElements = {} }: any) => { return <WrappedComponent {...props} backLabel={commonElements.backLabel || 'Go back to reservation details'} /> }; BackNavigationTextWrappedComponent.type = WrappedComponent.type; return BackNavigationTextWrappedComponent; }; J'obtiens une erreur "La propriété 'type' n'existe pas sur le type 'typeof Component'".
Si vous souhaitez prendre une classe de composant comme paramètre (par rapport à une instance), utilisez React.ComponentClass:
function renderGreeting(Elem: React.ComponentClass<any>) {
return <span>Hello, <Elem />!</span>;
}
React.ComponentType<any>type à la place pour les inclure.
Lorsque je convertis de JSX en TSX et que nous conservons certaines bibliothèques sous le nom js / jsx et convertissons d'autres en ts / tsx, j'oublie presque toujours de changer les instructions d'importation js / jsx dans les fichiers TSX \ TS de
import * as ComponentName from "ComponentName";
à
import ComponentName from "ComponentName";
Si vous appelez un ancien composant de style JSX (React.createClass) depuis TSX, utilisez
var ComponentName = require("ComponentName")
tsconfig.json) sur allowSyntheticDefaultImports. Voir: typescriptlang.org/docs/handbook/compiler-options.html et discussion ici: blog.jonasbandi.net/2016/10/…
Si vous ne vous souciez vraiment pas des accessoires, le type le plus large possible est React.ReactType.
Cela permettrait de passer des éléments dom natifs sous forme de chaîne. React.ReactTypecouvre tous ces éléments:
renderGreeting('button');
renderGreeting(() => 'Hello, World!');
renderGreeting(class Foo extends React.Component {
render() {
return 'Hello, World!'
}
});
Si vous utilisez material-ui , accédez à la définition de type du composant, qui est soulignée par TypeScript. Très probablement, vous verrez quelque chose comme ça
export { default } from './ComponentName';
Vous avez 2 options pour résoudre l'erreur:
1.Ajouter .defaultlors de l'utilisation du composant dans JSX:
import ComponentName from './ComponentName'
const Component = () => <ComponentName.default />
2.Renommez le composant, qui est exporté comme "par défaut", lors de l'importation:
import { default as ComponentName } from './ComponentName'
const Component = () => <ComponentName />
De cette façon, vous n'avez pas besoin de spécifier .defaultchaque fois que vous utilisez le composant.
Ce qui suit a fonctionné pour moi: https://github.com/microsoft/TypeScript/issues/28631#issuecomment-472606019 Je le corrige en faisant quelque chose comme ceci:
const Component = (isFoo ? FooComponent : BarComponent) as React.ElementType
Dans mon cas, j'utilisais React.ReactNodecomme type pour un composant fonctionnel au lieu de React.FCtype.
Dans ce composant pour être exact:
export const PropertiesList: React.FC = (props: any) => {
const list:string[] = [
' Consequat Phasellus sollicitudin.',
' Consequat Phasellus sollicitudin.',
'...'
]
return (
<List
header={<ListHeader heading="Properties List" />}
dataSource={list}
renderItem={(listItem, index) =>
<List.Item key={index}> {listItem } </List.Item>
}
/>
)
}
Comme @Jthorpe y a fait allusion, ComponentClassn'autorise que l'un Componentou l' autre PureComponentmais pas un FunctionComponent.
Si vous essayez de passer un FunctionComponent, dactylographié générera une erreur similaire à ...
Type '(props: myProps) => Element' provides no match for the signature 'new (props: myProps, context?: any): Component<myProps, any, any>'.
Cependant, en utilisant ComponentTypeplutôt que ComponentClassvous autorisez les deux cas. Selon le fichier de déclaration de réaction, le type est défini comme ...
type ComponentType<P = {}> = ComponentClass<P, any> | FunctionComponent<P>
Dans mon cas, je manquais newdans la définition de type.
some-js-component.d.ts fichier:
import * as React from "react";
export default class SomeJSXComponent extends React.Component<any, any> {
new (props: any, context?: any)
}
et dans le tsxfichier où j'essayais d'importer le composant non typé:
import SomeJSXComponent from 'some-js-component'
const NewComp = ({ asdf }: NewProps) => <SomeJSXComponent withProps={asdf} />
Lors de la déclaration du composant React Class, utilisez React.ComponentClass au lieu de React.Componentpuis cela corrigera l'erreur ts.
Vous pouvez utiliser
function renderGreeting(props: {Elem: React.Component<any, any>}) {
return <span>Hello, {props.Elem}!</span>;
}
Cependant, est-ce que ce qui suit fonctionne?
function renderGreeting(Elem: React.ComponentType) {
const propsToPass = {one: 1, two: 2};
return <span>Hello, <Elem {...propsToPass} />!</span>;
}
@types/react, il est plus facile à utiliserfunction RenderGreeting(Elem: React.ComponentType) { ... }