2017-07-11 5 views
8

J'utilise le Microsoft TypeScript-React-Starter et obtenu cette erreur de compilation lors de npm start:Le type d'élément JSX 'App' n'est pas une fonction de constructeur pour les éléments JSX. Types de propriété « setState » sont incompatibles

./src/index.tsx 
(16,5): error TS2605: JSX element type 'App' is not a constructor function for JSX elements. 
    Types of property 'setState' are incompatible. 
    Type '{ <K extends never>(f: (prevState: null, props: {}) => Pick<null, K>, callback?: (() => any) | un...' is not assignable to type '{ <K extends never>(f: (prevState: {}, props: any) => Pick<{}, K>, callback?: (() => any) | undef...'. 
     Types of parameters 'f' and 'f' are incompatible. 
     Type '(prevState: {}, props: any) => Pick<{}, any>' is not assignable to type '(prevState: null, props: {}) => Pick<null, any>'. 
      Types of parameters 'prevState' and 'prevState' are incompatible. 
      Type 'null' is not assignable to type '{}'. 

Il semble donc que ma fonction setState a signature incorrecte mais je ne suis pas sûr de savoir comment fixer . Voici mon code:

class App extends React.Component<{}, null> { 
    render() { 
    return (
     <div className="App"> 
     ... 
     </div> 
    ); 
    } 
} 

ReactDOM.render(
    <Provider store={store}> 
    <App /> 
    </Provider>, 
    document.getElementById('root') as HTMLElement 
); 

J'utilise:

node v6.11.0 
npm v5.1.0 
typescript v2.4.1 
react v15.6.1 
redux v3.7.1 
react-redux v5.0.5 
react-scripts-ts v2.3.2 

Mise à jour:

J'ai découvert que la suppression des types génériques <{}, null> efface l'erreur. Mais j'aimerais toujours savoir pourquoi j'ai eu l'erreur.

+0

Si le composant App n'utilise pas d'état, vous pouvez en faire un composant fonctionnel sans état à la place. –

+0

@ D-reaper 'App' utilise l'état dans mon cas. J'utilise 'redux' pour gérer l'état. Je suppose que c'est pourquoi je n'ai pas besoin d'écrire explicitement 'prevState()'? – CherryQu

+1

Je pense que puisque vous passez 'null' comme deuxième argument de type dans React.Component, qui définit la structure de l'état et qu'il est seulement compatible avec certains types (par exemple l'objet) provoquant ainsi TS à lancer cette erreur. '' ou simplement '<{}>' fonctionnerait également. –

Répondre

10

TLDR; L'état ne peut pas être nul. Déclarez une interface pour ou déclarer {}

réponse se trouve dans @types/react

En regardant le definition, ni l'état ni les accessoires ne sont pas destinés à être nulle. Lorsque vous avez déclaré App comme class App extends React.Component<{}, null> {, vous avez dit essentiellement que "l'état est de type null".

Maintenant, le type de setState dépend du type que vous spécifiez pour l'état et il est en conflit avec le lesser known version of the setState api. prevState est déclaré comme {} (la valeur par défaut, car aucune interface pour l'état n'a été spécifiée) qui n'est pas compatible avec null, ce qui conduit au journal des erreurs que vous avez vu.

+2

Étant donné que [ce PR] (https://github.com/DefinitelyTyped/DefinitelyTyped/pull/17288) a été fusionné, l'omission des paramètres de type entraîne la création du composant à l'aide des paramètres par défaut et d'état ('{}', ' {} '). Suppose TS> 2.3. – Cory

+0

Juste une note que nous avons obtenu ceci en utilisant 'void' aussi bien. Retrait de l'argument d'état entièrement et simplement en utilisant l'argument de propriété rend le compilateur heureux à nouveau. – icfantv