我有一个班级修饰符家族,我在许多班级都重复了。类似于以下内容:
@foo
@bar
@baz
export class MyClass { /* ..... */ }
由于我在多个类中使用了这三个装饰器,因此我很想将其分解为一个装饰器,如下所示:
@standard
export class MyClass { /* ... */ }
我试图创建一个新的类装饰器,将装饰器调用链接如下:
export function standard<ReturnType>(ctor: Constructor<ReturnType>) {
return baz(bar(foo(ctor)));
}
TypeScript手册说,应用多个装饰器应评估与函数组成相似的功能,这就是为什么我认为我应该能够将它们链接在一起的原因。但是,在编译时(使用TypeScript 1.8),出现类似以下错误
Unable to resolve signature of class decorator when called as an expression. Type 'Constructor<ReturnType>' is not assignable to type 'void'.
有没有办法构造这个“包装”装饰器来简化代码?
为了为@David构建我的问题的更完整版本,我弄清楚了哪里出了问题。
一个更完整的例子:
interface Constructor<T> { new(...args: any[]): T }
interface A { a: number; }
interface B { b: number; }
interface C { c: number; }
function foo(Target: Constructor<A>): Constructor<A>{
// do some stuff to the constructor
return Target;
}
function bar(Target: Constructor<B>): Constructor<B> {
// do some stuff to the constructor
return Target;
}
function baz(Target: Constructor<C>): Constructor<C> {
// ....
return Target;
}
function standard(ctor: Constructor<A & B & C>): Constructor<A & B & C> {
return baz(bar(foo(ctor)));
}
@foo
@bar
@baz
class MyClass implements A, B, C { a=1;b=2;c=3;d=6; }
我的实际代码中存在一些隐式键入,这在某种程度上掩盖了我的问题。而且显然我无法正确读取编译器输出。
问题在于我如何声明我的装饰器:
function foo(Target: Constructor<A>): Constructor<A> { }
需要
function foo<T extends A>(Target: Constructor<T>): Constructor<T> {}
我注意到,如果我在装饰器中设置了返回类型,any
则编译错误就消失了。额外的泛型参数使类型信息干净地流过装饰器。否则,我认为它(基本上)看到Constructor<MyClass>
无法分配的实例Constructor<A>
(因为A
缺少其他接口)。同样奇怪的是,如果我添加了d
in的声明,则会在装饰器中弹出更多错误MyClass
。
因此,在结束时-使用类修饰符时,请小心使用泛型,或者只是return any
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句