为什么会出现错误:错误TS2346:提供的参数与调用目标的任何签名都不匹配

时间:2016-11-07 12:56:33

标签: typescript

我尝试编译这个简单的代码:

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:提供的参数与呼叫目标的任何签名都不匹配。

错误的原因是什么?

1 个答案:

答案 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;
}

code in playground