Com*_*Cow 7 decorator typescript
我有一个类装饰器家族,我在许多类中重复使用它们。类似的东西:
@foo
@bar
@baz
export class MyClass { /* ..... */ }
Run Code Online (Sandbox Code Playgroud)
由于我在多个类中使用这三个装饰器,我真的很想将其分解为一个装饰器,如下所示:
@standard
export class MyClass { /* ... */ }
Run Code Online (Sandbox Code Playgroud)
我试图创建一个新的类装饰器,它像这样链接装饰器调用:
export function standard<ReturnType>(ctor: Constructor<ReturnType>) {
return baz(bar(foo(ctor)));
}
Run Code Online (Sandbox Code Playgroud)
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; }
Run Code Online (Sandbox Code Playgroud)
我的实际代码中存在一些隐式键入,这在某种程度上向我隐藏了问题。显然我无法正确读取编译器输出。
问题在于我如何声明我的装饰器:
function foo(Target: Constructor<A>): Constructor<A> { }
Run Code Online (Sandbox Code Playgroud)
需要是
function foo<T extends A>(Target: Constructor<T>): Constructor<T> {}
Run Code Online (Sandbox Code Playgroud)
我注意到如果我将装饰器中的返回类型设置为any编译错误就会消失。额外的泛型参数让类型信息干净地流经装饰器。否则我相信它(基本上)看到Constructor<MyClass>无法分配实例Constructor<A>(因为A缺少其他接口)。d另外奇怪的是,如果我添加in的声明,我会在装饰器中弹出更多错误MyClass。
所以最后 - 当使用类装饰器时,要小心你的泛型,或者只是 return any。
| 归档时间: |
|
| 查看次数: |
7101 次 |
| 最近记录: |