Typescript + React / Redux: la proprietà "XXX" non esiste nel tipo "IntrinsicAttributes & IntrinsicClassAttributes


96

Sto lavorando a un progetto con Typescript, React e Redux (tutti in esecuzione in Electron) e ho riscontrato un problema quando includo un componente basato sulla classe in un altro e provo a passare parametri tra di loro. In parole povere, ho la seguente struttura per il componente contenitore:

class ContainerComponent extends React.Component<any,any> {
  ..
  render() {
    const { propToPass } = this.props;
    ...
    <ChildComponent propToPass={propToPass} />
    ...
  }
}

....
export default connect(mapStateToProps, mapDispatchToProps)(ContainerComponent);

E il componente figlio:

interface IChildComponentProps extends React.Props<any> {
  propToPass: any
}

class ChildComponent extends React.Component<IChildComponentProps, any> {
  ...
}

....
export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);

Ovviamente sto solo includendo le basi e c'è molto di più in entrambe queste classi, ma ricevo ancora un errore quando provo ad eseguire quello che mi sembra codice valido. L'errore esatto che ricevo:

TS2339: Property 'propToPass' does not exist on type 'IntrinsicAttributes & IntrinsicClassAttributes<Component<{}, ComponentState>> & Readonly<{ childr...'.

Quando ho riscontrato l'errore per la prima volta ho pensato che fosse perché non stavo passando un'interfaccia che definiva i miei oggetti di scena, ma l'ho creata (come puoi vedere sopra) e ancora non funziona. Mi chiedo, c'è qualcosa che mi manca?

Quando escludo il prop ChildComponent dal codice in ContainerComponent, viene visualizzato correttamente (a parte il mio ChildComponent che non ha un prop critico) ma con esso nel Typescript JSX si rifiuta di compilarlo. Penso che potrebbe avere qualcosa a che fare con il connect wrapping basato su questo articolo , ma i problemi in quell'articolo si sono verificati nel file index.tsx ed erano un problema con il provider, e sto riscontrando i miei problemi altrove.

Risposte:


56

Quindi, dopo aver letto alcune risposte correlate (in particolare questa e questa e guardando la risposta di @ basarat alla domanda, sono riuscito a trovare qualcosa che funziona per me. Sembra (ai miei occhi React relativamente nuovi) che Connect non fornisse un un'interfaccia esplicita al componente contenitore, quindi è stato confuso dall'elica che stava cercando di passare.

Quindi il componente contenitore è rimasto lo stesso, ma il componente figlio è cambiato leggermente:

interface IChildComponentProps extends React.Props<any> {
  ... (other props needed by component)
}

interface PassedProps extends React.Props<any> {
  propToPass: any
}

class ChildComponent extends React.Component<IChildComponentProps & PassedProps, any> {
  ...
}

....
export default connect<{}, {}, PassedProps>(mapStateToProps, mapDispatchToProps)    (ChildComponent);

Quanto sopra è riuscito a funzionare per me. Passare esplicitamente gli oggetti di scena che il componente si aspetta dal contenitore sembra funzionare ed entrambi i componenti vengono visualizzati correttamente.

NOTA: So che questa è una risposta molto semplicistica e non sono esattamente sicuro del PERCHÉ funziona, quindi se un ninja React più esperto vuole approfondire questa risposta sarei felice di modificarla.


7
Ma React.Propsè stato deprecato !!
Sunil Sharma


0

Ricontrolla i tipi di oggetti appena aggiunti. Quando il tipo di oggetto non è esattamente come previsto, viene generato tale errore.

Ex. Il tipo di oggetti di scena menzionati nel componente deve corrispondere al tipo di oggetti di scena che vengono passati a quel componente.


-2

Invece di export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);, preferisci il connectdecoratore https://github.com/alm-tools/alm/blob/00f2f94efd3810af8a80a49f968c2ebdeb955399/src/app/fileTree.tsx#L136-L146

@connect((state: StoreState): Props => {
    return {
        filePaths: state.filePaths,
        filePathsCompleted: state.filePathsCompleted,
        rootDir: state.rootDir,
        activeProjectFilePathTruthTable: state.activeProjectFilePathTruthTable,
        fileTreeShown: state.fileTreeShown,
    };
})

Dove la connessione è definita qui https://github.com/alm-tools/alm/blob/00f2f94efd3810af8a80a49f968c2ebdeb955399/src/typings/react-redux/react-redux.d.ts#L6-L36

Perché?

Sembra che le definizioni che stai utilizzando siano probabilmente obsolete o non valide (forse di scarsa qualità).


3
Sembra che la connessione sul componente figlio fosse sicuramente il problema, ma ho trovato un modo per risolvere il problema senza modificare la digitazione che stavo usando. Utilizzando la soluzione in questo link sono riuscito a cambiare la mia connessione a: connect<{}, {}, PassedProps> Dove PassedProps è il puntello che il componente ottiene dal suo contenitore principale.
Protagonista
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.