Estoy escribiendo un componente de orden superior para mi proyecto React usando Typescript, que es básicamente una función que acepta un componente React como argumento y devuelve un nuevo componente que lo envuelve.
Sin embargo, como funciona como se esperaba, TS se queja de que "el tipo de retorno de la función exportada tiene o está usando el nombre privado "clase anónima".
Función en cuestión:
export default function wrapperFunc <Props, State> ( WrappedComponent: typeof React.Component, ) { return class extends React.Component<Props & State, {}> { public render() { return <WrappedComponent {...this.props} {...this.state} />; } }; }El error es razonable ya que la clase de retorno de la función contenedora no se exporta y otro módulo importa esta función no tiene forma de saber cuál sería el valor de retorno. Pero no puedo declarar la clase de retorno fuera de esta función, ya que requiere envolver un pase de componente a la función externa.
Una prueba con la especificación explícita del tipo de retorno typeof React.Component como a continuación suprime este error.
Función en cuestión con tipo de retorno explícito:
export default function wrapperFunc <Props, State> ( WrappedComponent: typeof React.Component, ): typeof React.Component { // <== Added this return class extends React.Component<Props & State, {}> { public render() { return <WrappedComponent {...this.props} {...this.state} />; } }; }Sin embargo, no estoy seguro acerca de la validez de este enfoque. ¿Se considera un enfoque correcto para abordar este error en particular en TypeScript? (¿O estoy creando efectos secundarios no deseados en otro lugar? ¿O alguna forma mejor de hacerlo?)
(Editar) Cambie el código citado según la sugerencia de Daniel.
Escriba la anotación para React Higher Order Component usando TypeScript
El tipo de retorno typeof React.Component es veraz, pero no muy útil para los usuarios del componente envuelto. Descarta información sobre qué props acepta el componente.
Los tipos de React proporcionan un tipo útil para este propósito, React.ComponentClass . Es el tipo de una clase, en lugar del tipo del componente creado a partir de esa clase:
React.ComponentClass<Props> (Tenga en cuenta que el tipo de state no se menciona ya que es un detalle interno).
En tu caso:
export default function wrapperFunc <Props, State, CompState> ( WrappedComponent: typeof React.Component, ): React.ComponentClass<Props & State> { return class extends React.Component<Props & State, CompState> { public render() { return <WrappedComponent {...this.props} {...this.state} />; } }; } Sin embargo, está haciendo lo mismo con el parámetro WrappedComponent . Según cómo lo esté usando dentro de render , supongo que también debería declararse:
WrappedComponent: React.ComponentClass<Props & State>, Pero esto es una suposición descabellada, ya que asumo que esta no es la función completa ( CompState no se usa, y Props & State también puede ser un parámetro de tipo único, ya que siempre aparece en esa combinación).
Un tipo más apropiado para el parámetro de entrada sería React.ComponentType , ya que también maneja componentes sin estado.
type ComponentType<P = {}> = ComponentClass<P> | StatelessComponent<P>A continuación se muestra un ejemplo que aclara su uso.
import * as React from 'react'; export default function <P = {}>( WrappedComponent: React.ComponentType<P> ): React.ComponentClass<P> { return class extends React.Component<P> { render() { return <WrappedComponent {...this.props} />; } }; }