TypeScript和React:如何重载高阶组件/装饰器?

时间:2018-11-28 07:49:30

标签: reactjs typescript typescript-typings higher-order-components typescript-types

我正在使用TypeScript构建React应用。

我正在写一个更高阶的组件,我想重载它的参数。我该怎么办?

让我给您我尝试过的内容,以便您可以更好地理解:

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

因此应该是:

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

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

显然,TypeScript在这里抱怨,因为它希望=>紧跟valueanotherValue的括号之后(因为它认为这是一个函数)。但是,如何重载此HOC的参数?

顺便说一句::此HOC将一个组件与另一个组件分组:

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

我想重载HOC的参数,因为有几个值很可能被修改(valueanotherValue),如果不是,则该组件应该可以通过completeProps进行完全自定义。

编辑:

该问题被标记为this的可能重复项。但是我的问题有所不同,因为它是关于高阶组件的。标记的问题仅涉及简单函数,而不涉及返回其他返回类的函数的函数。

1 个答案:

答案 0 :(得分:1)

箭头函数没有显式的重载语法,可以改用常规函数:

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

您还可以使用箭头功能,但需要显式键入:

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