当使用React 16新功能:componentDidCatch时,我尝试编写一个HOC来抽象代码。并用装饰器来实现它。 代码如下:
import * as React from 'react';
export function catcher<P, T extends React.ComponentClass<P>>(Target: T): T {
class HOC extends Target {
}
return HOC;
}
然后像这样使用它:
@catcher
export class Foo extends React.Component {}
但是,出现错误
[ts] Type 'T' is not a constructor function type.
[ts] Type 'typeof HOC' is not assignable to type 'T'
最佳答案
docs假设装饰器的第一个参数是构造函数,所以我们必须给 T 一个构造函数签名。文档中的示例具有返回 {}
的构造函数,但如果我们想确保装饰器不能仅用于任何类型,而必须用于 React.Component
我们可以让构造函数返回一个 React.Component
,因此传递的任何构造函数都必须返回一个 React.Component
或兼容的(实际上必须派生自 React.Component
)
export function catcher<S, P, T extends { new (... args:any[]): React.Component<S, P> }>(constructor:T) {
class HOC extends constructor {
}
return HOC;
}
@catcher
export class Foo extends React.Component {
}
@catcher // Will be an error, Foo2 is not derived from React.Component
export class Foo2 {
}
构造函数签名的另一种语法是:
export function catcher<S, P, T extends new (... args:any[]) => React.Component<S, P>>(constructor:T) {
class HOC extends constructor {
}
return HOC;
}
关于javascript - TypeScript generic 编写装饰器时出错?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47016598/