TypeScript装饰器报告“当作为表达式调用时无法解析类装饰器的签名”

时间:2016-04-06 09:09:41

标签: typescript

@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执行得很好。我不知道为什么报错。

4 个答案:

答案 0 :(得分:11)

编译器希望你的装饰器无效或返回一个与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:

  

注意您是否应该选择返回新的构造函数   注意保持原始原型。适用的逻辑   运行时的装饰器不会为你做这个。

答案 1 :(得分:7)

似乎可以通过在tsconfig.json中添加ES2016或ES5作为目标来解决此问题

https://github.com/alsatian-test/alsatian/issues/344#issuecomment-290418311

答案 2 :(得分:1)

如上面的Alex所述,编译器希望您的装饰器为void或返回与A兼容的值。因此,您可以将ff强制转换为typeof target

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

答案 3 :(得分:1)

我的问题是我的 tsconfig.json 的 "experimentalDecorators": true 中仍然有 compilerOptions,但最新版本的 TypeScript 不再需要它了。