Type annotation for a higher repeat component using TypeScript

I am writing a higher order component for my React project using Typescript, which is basically a function that takes a React component as an argument and returns a new component that wraps around it.

However, since it works as expected, TS complains that "The return type of the exported function has or uses the private name" Anonymous Class ".

Function in question:

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} />; } }; } 

The error is reasonable, since the return class of the wrapper function is not exported, and another module imports this function, unable to find out what the return value will be. But I can not declare the returned class outside this function, as it requires the package to pass an external function.

A trial version with an explicit type return typeof React.Component , as shown below, suppresses this error.

The function in question with an explicit return type:

 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} />; } }; } 

However, I am not sure of the validity of this approach. Is this the right approach to solve this particular error in TypeScript? (Or am I creating unintended side effects elsewhere? Or is there any better way to do this?)

(Modify) Modify the quotation code as proposed by Daniel.

+5
source share
2 answers

Enter an annotation to reference a higher-order component using TypeScript

The typeof React.Component return type is true, but not very useful for users of the wrapped component. It discards information about which details the component accepts.

Typical React data provides a convenient type for this purpose, React.ComponentClass . Its class type, not the type of component created from this class:

 React.ComponentClass<Props> 

(Note that the state type is not referred to as its internal part).

In your case:

 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} />; } }; } 

However, you are doing the same with the WrappedComponent parameter. Based on how you use it inside render , I assume that it should also be declared:

 WrappedComponent: React.ComponentClass<Props & State>, 

But this is a wild assumption, since I assume that this is not a complete function ( CompState isnt used, and Props & State can also be a parameter of the same type, since it always appears in this combination).

+3
source

A more appropriate type for the input parameter would be React.ComponentType , since it also handles stateless components.

 type ComponentType<P = {}> = ComponentClass<P> | StatelessComponent<P> 

The following is an example explaining its use.

 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} />; } }; } 
0
source

Source: https://habr.com/ru/post/1262402/


All Articles