2016-04-06 37 views
13
@xxx("xxx") 
class A{ 
    msg:string 
    constructor(msg:string) { 
     this.msg = msg 
    } 
    print() { 
     console.log(this.msg) 
    } 
} 

function xxx(arg:string) { 
    function f(target) { 
     function ff(msg: string) { 
      return new target(arg + ":" + msg) 
     } 
     return ff 
    } 
    return f 
} 

let a = new A("hellow") 
a.print() 

当编译,它报告:打字稿装饰报告“无法调用时作为表达解决类装饰的签名”

decorator.ts(1,1):错误TS1238:无法解析签名当作为表达式调用类装饰器时。 输入'(msg:string)=>任何'不可分配为输入'void'。

但是,被控制的js执行得很好。我不知道为什么报告错误。

+5

也确保你调用'@Input()'带括号'()',因为它的函数。 – STEEL

回答

6

编译器期望你的装饰要么无效或返回一个值,该值是与A兼容它看到你返回(msg:any) => any,但不能得出这样的结论,这个功能是A.

如果兼容想摆脱错误的,你可以投的FF任何时候你回吧,或者甚至到typeof A沟通的意图更加清晰:

function xxx(arg: string) 
{ 
    function f(target) 
    { 
     function ff(msg: string) 
     { 
      return new target(arg + ":" + msg) 
     } 
     return <typeof A><any>ff 
    } 
    return f 
} 

这就是说,它可能不是更换班是个好主意像这样,你至少应该维护构造函数:

TypeScript documentation:

注意如果您选择返回一个新的构造函数,你必须 照顾,以保持原有的原型。运行时应用 装饰器的逻辑将不会为您执行此操作。

+0

非常感谢。铸造技术正是我所需要的。我不需要用加倍投射,就足够了。如果可以的话,会让你赞赏两次。 –

+0

你如何以通用的方式做到这一点?如果我必须投入到类中,我将装饰器放置在如何转换为装饰器所在的类型而不用硬编码的类型? – chubbsondubs

+0

@chubbsondubs我也想这样做,但我认为我没有找到任何解决方案。也许我们现在有一些新的语法,我不知道。我认为其中一个问题是类的构造函数的类型没有对类的类型引用:https://github.com/Microsoft/TypeScript/issues/3841 – Alex