reactjs - ¿Por qué el tipo no se puede asignar al tipo genérico?
Estoy intentando construir y tipar un HOC que simplemente envuelva un componente en un ApolloProvider. Me gustaría poder pasar el ref al componente envuelto. Sin embargo, cuando intento pasar las props en el componente forwardRef, estoy obteniendo errores de tipo
En algún momento durante mi racha de investigación me topé con una respuesta que hablaba de que los genéricos eran el problema.
const withProvider = function<P>(WrappedComponent: React.ComponentClass<P>) {
type Props = P & { forwardedRef?: React.Ref<any> }
class WithProvider extends React.Component<Props> {
render() {
const { forwardedRef, ...props } = this.props
return (
<ApolloProvider client={client}>
<WrappedComponent {...props} ref={forwardedRef} />
</ApolloProvider>
)
}
}
hoistNonReactStatics(WithProvider, WrappedComponent)
return React.forwardRef((props, ref) => (
<WithProvider {...props} forwardedRef={ref} />
))
}
Me da el error:
Type '{ forwardedRef: string | ((instance: {} | null) => any) | RefObject<{}> | undefined; children?: ReactNode; }' is not assignable to type 'Readonly<Props>'
Para mí, estos deberían coincidir y el primero debería poder asignarse al segundo. Lo único que se me ocurre es que Readonly<Props> contiene un genérico.
¿Alguien puede señalarme la dirección correcta?
Respuesta #1
Finalmente, encontré la solución.
Todo lo que tienes que hacer es dar el tipo de props (en
React.forwardRef) como el tipo recibido que esP.
return React.forwardRef((props:P, ref) => (
<WithProvider {...props} forwardedRef={ref} />
));
Código completo:
const withProvider = function<P>(WrappedComponent: React.ComponentClass<P>) {
type Props = P & { forwardedRef?: React.Ref<any> }
class WithProvider extends React.Component<Props> {
render() {
const { forwardedRef, ...props } = this.props
return (
<ApolloProvider client={client}>
<WrappedComponent {...props} ref={forwardedRef} />
</ApolloProvider>
)
}
}
hoistNonReactStatics(WithProvider, WrappedComponent)
return React.forwardRef((props:P, ref) => (
<WithProvider {...props} forwardedRef={ref} />
))
}
