Typecript + React / Redux: la propiedad "XXX" no existe en el tipo 'IntrinsicAttributes & IntrinsicClassAttributes

91

Estoy trabajando en un proyecto con Typescript, React y Redux (todos ejecutándose en Electron), y me he encontrado con un problema cuando incluyo un componente basado en clases en otro y trato de pasar parámetros entre ellos. Hablando libremente, tengo la siguiente estructura para el componente contenedor:

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

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

Y el componente hijo:

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

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

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

Obviamente, solo incluyo lo básico y hay mucho más en ambas clases, pero sigo recibiendo un error cuando intento ejecutar lo que me parece un código válido. El error exacto que obtengo:

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

Cuando encontré el error por primera vez, pensé que era porque no estaba pasando una interfaz que definiera mis accesorios, pero lo creé (como puede ver arriba) y todavía no funciona. Me pregunto, ¿hay algo que me esté perdiendo?

Cuando excluyo el accesorio ChildComponent del código en el ContainerComponent, se muestra bien (aparte de que mi ChildComponent no tiene un accesorio crítico) pero con él en JSX Typecript se niega a compilarlo. Creo que podría tener algo que ver con la envoltura de conexión basada en este artículo. , pero los problemas en ese artículo ocurrieron en el archivo index.tsx y fueron un problema con el proveedor, y tengo mis problemas en otra parte.

Protagonista
fuente

Respuestas:

54

Entonces, después de leer algunas respuestas relacionadas (específicamente esta y esta y mirar la respuesta de @ basarat a la pregunta, logré encontrar algo que funciona para mí. Parece (para mis ojos de React relativamente nuevos) que Connect no estaba proporcionando un interfaz explícita al componente contenedor, por lo que estaba confundido por el accesorio que estaba tratando de pasar.

Entonces, el componente contenedor se mantuvo igual, pero el componente secundario cambió un poco:

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);

Lo anterior logró funcionar para mí. Pasar explícitamente los accesorios que el componente espera del contenedor pareció funcionar y ambos componentes se procesaron correctamente.

NOTA: Sé que esta es una respuesta muy simplista y no estoy exactamente seguro de POR QUÉ funciona, así que si un ninja de React con más experiencia quiere dejar algo de conocimiento sobre esta respuesta, me complacerá enmendarla.

Protagonista
fuente
7
¡Pero React.Propsha sido desaprobado!
Sunil Sharma
-1

En lugar de export default connect(mapStateToProps, mapDispatchToProps)(ChildComponent);, prefiera el connectdecorador 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,
    };
})

Donde conectar se define aquí https://github.com/alm-tools/alm/blob/00f2f94efd3810af8a80a49f968c2ebdeb955399/src/typings/react-redux/react-redux.d.ts#L6-L36

¿Por qué?

Parece que las definiciones que está utilizando probablemente estén desactualizadas o no sean válidas (tal vez estén mal escritas).

basarat
fuente
2
Parece que la conexión en el componente secundario fue definitivamente el problema, pero encontré una manera de resolver el problema sin cambiar los tipos de escritura que estaba usando. Usando la solución en este enlace , logré cambiar mi conexión a: connect<{}, {}, PassedProps> Donde PassedProps es el accesorio que el componente obtiene de su contenedor principal.
Protagonista