TypeScript 装饰器报告“当作为表达式调用时无法解析类装饰器的签名”
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/36446480/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
TypeScript decorator reports "Unable to resolve signature of class decorator when called as an expression"
提问by cloud
@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. Type '(msg: string) => any' is not assignable to type 'void'.
decorator.ts(1,1):错误 TS1238:当作为表达式调用时,无法解析类装饰器的签名。类型 '(msg: string) => any' 不能分配给类型 'void'。
But the genrated js executed well. I don't know why report error.
但是生成的 js 执行得很好。不知道为什么报错。
采纳答案by Alex
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.
编译器希望你的装饰器要么是空的,要么返回一个与 A 兼容的值。它看到你返回 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:
也就是说,像这样替换类可能不是一个好主意,您至少应该维护构造函数:
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.
注意 如果您选择返回一个新的构造函数,您必须注意维护原始原型。在运行时应用装饰器的逻辑不会为您执行此操作。
回答by URL87
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
回答by hudingyu
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 提到的,编译器希望你的装饰器要么是空的,要么返回一个与 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
}