我有一个类装饰器家族,我在很多类中重复使用它们。与此类似的东西:
@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>
(since A
缺少其他接口)。另外奇怪的是,如果我添加了该声明,我会在装饰器中弹出更多错误d
in MyClass
.
所以最后 - 当使用类装饰器时,要小心你的泛型,或者只是返回any
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)