Typescript 高阶组件作为装饰器
Typescript Higher Order Component as Decorator
我正在尝试在我的 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> }
}
这个returns错误:
'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'.'
我真的不明白为什么会出现这个错误。我一定做错了什么。一旦我介绍了道具,事情就变得更加毛茸茸了。
我将不胜感激正确的解决方案,但我也很想首先了解为什么会出现此错误。
谢谢!
一个 class 装饰器,其 return 的值类似于
const Link = withDecorator(class extends Component<object, object> {
render() {
return <a href="/">Link</a>
}
instanceMethod() { return 2 }
static classMethod() { return 2 }
})
TypeScript 期望装饰器的 return 值与输入具有相同的类型,因此结果仍然具有相同的行为。 在您的示例中,呈现类型签名不匹配,但随着添加的方法,问题更加明显:使用装饰器的实现,以下将失败:
new Link().instanceMethod()
Link.classMethod()
正确的类型签名应该是:
function withDecorator<T extends React.ComponentClass>(Wrapped: T): T
并且实现也应该匹配,最简单的方法是扩展目标 class:
return class extends Wrapped { ... }
请注意,使用 React HOC,您不一定要扩展 class,因此使用装饰器可能不是最佳解决方案。
我正在尝试在我的 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> }
}
这个returns错误:
'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'.'
我真的不明白为什么会出现这个错误。我一定做错了什么。一旦我介绍了道具,事情就变得更加毛茸茸了。
我将不胜感激正确的解决方案,但我也很想首先了解为什么会出现此错误。
谢谢!
一个 class 装饰器,其 return 的值类似于
const Link = withDecorator(class extends Component<object, object> {
render() {
return <a href="/">Link</a>
}
instanceMethod() { return 2 }
static classMethod() { return 2 }
})
TypeScript 期望装饰器的 return 值与输入具有相同的类型,因此结果仍然具有相同的行为。 在您的示例中,呈现类型签名不匹配,但随着添加的方法,问题更加明显:使用装饰器的实现,以下将失败:
new Link().instanceMethod()
Link.classMethod()
正确的类型签名应该是:
function withDecorator<T extends React.ComponentClass>(Wrapped: T): T
并且实现也应该匹配,最简单的方法是扩展目标 class:
return class extends Wrapped { ... }
请注意,使用 React HOC,您不一定要扩展 class,因此使用装饰器可能不是最佳解决方案。