TypeScript and React: How to overload a higher order component / decorator?

折月煮酒 提交于 2021-01-29 08:01:05

问题


I'm building a React app using TypeScript.

I'm writing a higher order component and I would like to overload it's arguments. How can I do that?

Let me give you what I've tried so that you can understand it better:

const myHOC = ((value: string, anotherValue: number) | completeProps: SomeProps) => (WrappedComponent: ComponentClass) => // ... HOC code

So it should be either:

const myHOC = (value: string, anotherValue: number) => (WrappedComponent: ComponentClass) => // ...

or

const myHOC = (completeProps: SomeProps) => (WrappedComponent: ComponentClass) => // ...

Obviously TypeScript complains here, because it expects a => to come after the brackets surrounding value and anotherValue (because it thinks that is a function). But how can I overload this HOC's parameters?

BTW: This HOC groups a component with another:

<React.Fragment>
  <WrappedComponent {this.props} />
  <ComponentInjectedByHOC valueProp={value} anotherValueProp={anotherValue} {...completeProps} />
</React.Fragment>

I would like to overload the parameters of the HOC, because there are a couple of values that have a high likely hood of being modified (value and anotherValue) and if not the component should just be completely customisable via the completeProps.

Edit:

This question has been marked as a possible duplicate ofthis. But my question is different, because it is about higher order components. The marked question only deals with simple functions, not functions than return another function that return a class.


回答1:


Arrow functions don't have explicit overload syntax, you can use a regular function instead:

interface SomeProps {value: string, anotherValue: number}
function myHOC (value: string, anotherValue: number) : (WrappedComponent: ComponentClass) => JSX.Element
function myHOC (completeProps: SomeProps) : (WrappedComponent: ComponentClass) => JSX.Element
function myHOC (valueOrCompleteProps: string| SomeProps, maybeAnotherValue?: number) : (WrappedComponent: ComponentClass) => JSX.Element {
    let completeProps: SomeProps;
    if(typeof valueOrCompleteProps ==='string') {
        completeProps = { value: valueOrCompleteProps, anotherValue: maybeAnotherValue! }
    }else{
        completeProps =valueOrCompleteProps;
    }

    return (WrappedComponent: ComponentClass) => <WrappedComponent {... completeProps} />
}

You can also use an arrow function but you need to type it explicitly:

interface SomeProps {value: string, anotherValue: number}
const myHOC : {
    (value: string, anotherValue: number) : (WrappedComponent: ComponentClass) => JSX.Element
    (completeProps: SomeProps) : (WrappedComponent: ComponentClass) => JSX.Element
} = (valueOrCompleteProps: string| SomeProps, maybeAnotherValue?: number) => {
    let completeProps: SomeProps;
    if(typeof valueOrCompleteProps ==='string') {
        completeProps = { value: valueOrCompleteProps, anotherValue: maybeAnotherValue! }
    }else{
        completeProps =valueOrCompleteProps;
    }

    return (WrappedComponent: ComponentClass) => <WrappedComponent {... completeProps} />
}


来源:https://stackoverflow.com/questions/53514525/typescript-and-react-how-to-overload-a-higher-order-component-decorator

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!