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

Posted

技术标签:

【中文标题】TypeScript 和 React:如何重载高阶组件/装饰器?【英文标题】:TypeScript and React: How to overload a higher order component / decorator? 【发布时间】:2019-04-30 01:41:25 【问题描述】:

我正在使用 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 的可能重复项。但我的问题不同,因为它是关于高阶组件的。标记的问题只处理简单函数,而不是返回另一个返回类的函数。

【问题讨论】:

你的语法没有让我清楚你的意图,重载是什么?一个需要(value: string, anotherValue: number) =&gt; (WrappedComponent: ComponentClass) =&gt;... 和另一个(completeProps: SomeProps) =&gt; (WrappedComponent: ComponentClass)=&gt;... @TitianCernicova-Dragomir 是的,这是正确的!我明确添加了。 Is there a way to do method overloading in TypeScript?的可能重复 【参考方案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 />

【讨论】:

以上是关于TypeScript 和 React:如何重载高阶组件/装饰器?的主要内容,如果未能解决你的问题,请参考以下文章

制作一个高阶组件以与 TypeScript 互操作 react-relay 和 react-router

在 TypeScript 中使用高阶组件在使用时省略 React 属性

Typescript:React Context 高阶组件类型错误

没有重载匹配此调用。 React 中的 Typescript 和 StyledComponents

使用 graphql 将道具传递给高阶组件时出现 React-apollo Typescript 错误

React Typescript 泛型类型重载(例如 useState)