我尝试编译这个简单的代码:
class C {
@log
foo(n: number) {
return n * 2;
}
}
function log(target: Function, key: string, value: any) {
return {
value: function (...args: any[]) {
var a = args.map(a => JSON.stringify(a)).join();
var result = value.value.apply(this, args);
var r = JSON.stringify(result);
console.log(`Call: ${key}(${a}) => ${r}`);
return result;
}
};
}
编译时出现错误:错误TS2346:提供的参数与呼叫目标的任何签名都不匹配。
错误的原因是什么?
答案 0 :(得分:0)
装饰器功能接收的参数应该不同,如in the docs所述:
function (target: any, propertyKey: string, descriptor: PropertyDescriptor)
在您的代码中target
的类型为Function
,因此编译器会抱怨:
“C”类型的参数不能分配给“函数”类型的参数 “C”类型中缺少属性“apply”。
如果您将其更改为文档中的any
,那么它可以正常工作,您也可以将其更改为C
,但它只适用于类C
而不适用于其他类。
此外,您可以稍微修改装饰器功能,因为您返回的描述符仅包含value
属性。
相反,您最好复制先前的描述符并更改value
:
function log(target: C, key: string, descriptor: PropertyDescriptor) {
let newDescriptor: PropertyDescriptor = Object.assign({}, descriptor);
newDescriptor.value = function (...args: any[]) {
var a = args.map(a => JSON.stringify(a)).join();
var result = descriptor.value.apply(this, args);
var r = JSON.stringify(result);
console.log(`Call: ${key}(${a}) => ${r}`);
return result;
}
return newDescriptor;
}