【问题标题】:Typescript Higher Order Component as DecoratorTypescript 高阶组件作为装饰器
【发布时间】:2018-04-07 00:08:49
【问题描述】:

我正在尝试在我的 React 项目中使用 Typescript,但在获取我的 HOC 功能的类型时遇到了困难。这是一个最小的示例来展示我遇到的问题:

const withDecorator =
    (Wrapped: React.ComponentType): React.ComponentClass =>
        class withDecorator extends Component {
            render() {
                return <Wrapped {...this.props} />
            }
        }

@withDecorator
class Link extends Component<object, object> {
    render() { return <a href="/">Link</a> }
}

这会返回错误:

'Unable to resolve signature of class decorator when called as an expression.
Type 'ComponentClass<{}>' is not assignable to type 'typeof Link'.
    Type 'Component<{}, ComponentState>' is not assignable to type 'Link'.
    Types of property 'render' are incompatible.
        Type '() => string | number | false | Element | Element[] | ReactPortal | null' is not assignable to type '() => Element'.
        Type 'string | number | false | Element | Element[] | ReactPortal | null' is not assignable to type 'Element'.
            Type 'null' is not assignable to type 'Element'.'

我真的不明白为什么会出现这个错误。我一定做错了什么。一旦我介绍了道具,事情就变得更加棘手了。

我将非常感谢正确的解决方案,但我也很想了解为什么会首先出现此错误。

谢谢!

【问题讨论】:

    标签: reactjs typescript higher-order-components


    【解决方案1】:

    返回值的类装饰器类似于做

    const Link = withDecorator(class extends Component<object, object> {
        render() { 
            return <a href="/">Link</a> 
        }
        instanceMethod() { return 2 }
        static classMethod() { return 2 }
    })
    

    TypeScript 期望装饰器的返回值与输入具有相同的类型,因此结果仍然具有相同的行为。 在您的示例中,渲染类型签名不匹配,但与添加的方法问题更加明显:使用您的装饰器实现,以下操作将失败:

    new Link().instanceMethod()
    Link.classMethod()
    

    正确的类型签名应该是:

    function withDecorator<T extends React.ComponentClass>(Wrapped: T): T
    

    并且实现也应该匹配,最容易通过扩展目标类:

    return class extends Wrapped { ... }
    

    请注意,使用 React HOC,您不一定要扩展类,因此使用装饰器可能不是最佳解决方案。

    另见https://github.com/Microsoft/TypeScript/issues/9453

    【讨论】:

    • 感谢您的回复!我想我认为装饰器是语法糖,用于用允许更改类签名的函数包装类。我看到它被一些库这样使用,但是 Typescript 对装饰器的工作方式有更保守的看法。
    猜你喜欢
    • 2019-04-30
    • 2018-04-06
    • 2016-12-12
    • 2021-10-08
    • 1970-01-01
    • 2018-11-12
    • 1970-01-01
    • 2019-07-25
    • 1970-01-01
    相关资源
    最近更新 更多