简体   繁体   English

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

[英]TypeScript decorator reports "Unable to resolve signature of class decorator when called as an expression"

@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()

When compile, it reports:编译时,它报告:

decorator.ts(1,1): error TS1238: Unable to resolve signature of class decorator when called as an expression. decorator.ts(1,1):错误 TS1238:当作为表达式调用时,无法解析 class 装饰器的签名。 Type '(msg: string) => any' is not assignable to type 'void'.类型“(msg: string) => any”不可分配给类型“void”。

But the genrated js executed well.但是生成的js执行得很好。 I don't know why it reports an error.不知道为什么会报错。

The compiler expects your decorator to either be void or return a value that is compatible with A. It sees that you return a (msg:any) => any but can not draw the conclusion that this function is compatible with A.编译器希望您的装饰器为 void 或返回与 A 兼容的值。它看到您返回(msg:any) => any但不能得出此函数与 A 兼容的结论。

If you want to get rid of the error, you can cast the ff to any when you return it, or maybe even to typeof A to communicate the intention clearer:如果您想摆脱错误,您可以在返回时将 ff 强制转换为 any ,或者甚至可以将其强制转换为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
}

That said, it's probably not a good idea to replace classes like this, you should at least maintain the constructor:也就是说,替换这样的类可能不是一个好主意,您至少应该维护构造函数:

TypeScript documentation:打字稿文档:

NOTE Should you chose to return a new constructor function, you must take care to maintain the original prototype.注意 如果您选择返回一个新的构造函数,您必须注意维护原始原型。 The logic that applies decorators at runtime will not do this for you.在运行时应用装饰器的逻辑不会为您执行此操作。

This appears to be resolved by adding ES2016 or ES5 as the target in tsconfig.json这似乎可以通过在 tsconfig.json 中添加 ES2016 或 ES5 作为目标来解决

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

As mentioned by Alex above, the compiler expects your decorator to either be void or return a value that is compatible with A. So you can cast the ff to typeof target .正如上面 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
}

For anyone that must have been facing this issue in 2022. It took me a long time but I realized that I was using an arrow functions.对于 2022 年一定遇到过这个问题的任何人。我花了很长时间,但我意识到我正在使用箭头功能。 Decorators will not work on arrow functions.装饰器不适用于箭头功能。 When I changed it, it worked smoothly.当我改变它时,它工作得很顺利。

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 Vuex 模块中的 Typescript 错误“无法解析 class 装饰器的签名” - Typescript error “Unable to resolve signature of class decorator when called as an expression” in Vuex module Typescript 中的装饰器错误:作为表达式调用时无法解析属性装饰器的签名.ts(1240) - Error with decorator in Typescript: Unable to resolve signature of property decorator when called as an expression.ts(1240) 作为表达式调用时无法解析属性装饰器的签名 - Unable to resolve signature of property decorator when called as an expression 打字稿 TS1241:作为表达式调用时无法解析方法装饰器的签名 - typescript TS1241: Unable to resolve signature of method decorator when called as an expression 为什么`错误:(3,1)TS1238:当作为表达式`错误调用时,无法解析类装饰器的签名 - Why `Error:(3, 1) TS1238:Unable to resolve signature of class decorator when called as an expression` error TS1238:当作为表达式调用时,无法解析类装饰器的签名 - TS1238: Unable to resolve signature of class decorator when called as an expression @Reflect.metadata 生成错误 TS1238:当作为表达式调用时无法解析类装饰器的签名 - @Reflect.metadata generates error TS1238: Unable to resolve signature of class decorator when called as an expression 出现错误TS1241:作为表达式调用时,无法解析方法装饰器的签名 - Getting error TS1241: Unable to resolve signature of method decorator when called as an expression 从另一个文件导入时无法解析Typescript装饰器的签名 - Unable to resolve signature of Typescript decorator when imported from another file Typescript 无法在 vscode 中解析装饰器参数的签名 - Typescript Unable to resolve signature of parameter of decorator in vscode
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM