类型'Function'的参数不能分配给类型'(... args:any [])=> void'的参数

时间:2018-08-08 10:55:23

标签: typescript

function on(event: string, listener: Function) {
    console.log('on event: ', event, 'typeof listener:', typeof (listener));
    listener();
}

function on1(event: string, listener: (...args: any[]) => void) {
    console.log('on event: ', event, 'typeof listener:', typeof (listener));
    listener();
}

function createCallback(a: number): Function {
    let f = (a: number) => {
        console.log('return a:', a);
        return (a: number) => { return a + 1 };
    };
    return f(a);
}

let f = createCallback(1);
console.log('type of f', typeof (f));
// on("start", f);
on1("start", f);

在上面的代码中,on("start", f)可以正常工作,但是on1("start", f);返回错误

main.ts:22:14 - error TS2345: Argument of type 'Function' is not assignable to parameter of type '(...args: any[]) => void'.
  Type 'Function' provides no match for the signature '(...args: any[]): void'.

22 on1("start", f);
                ~

如果我删除了Function的{​​{1}}类型断言,则createCallback有用,on1("start", f)是不是通用类型来表示闭包吗?

最初的问题来自此提交https://github.com/DefinitelyTyped/DefinitelyTyped/commit/96545154cc6488643a7064a6dc4ec9726c7af12a#diff-7d84e08967cded0b99ed4328aab0a1a8L291

我不明白他为什么将Function更改为Function,这使我的代码中断了。

1 个答案:

答案 0 :(得分:2)

有一个suggestion允许类似的内容,以便Function可分配给(...args: any[]) => any。并非当前行为的原因是:

  

Function的初衷是不可调用的。换句话说,“函数到函数”类型应该与其他类型一样,但不可调用。从那以后,我们放宽了此限制,通过特殊的大小写使Function在编译器中具有可调用的行为。我们已经讨论过使它成为--noImplicitAny错误,因为调用函数确实不安全。

如果这对您很重要,我建议您投票反对该建议。

我通常会远离Function,这不是表示函数签名的类型安全的方法。对于您的情况,我将使用以下内容:

function on(event: string, listener: (...args: any[]) => void) {
    console.log('on event: ', event, 'typeof listener:', typeof (listener));
    listener();
}

function createCallback(a: number)  { // we can omit the return type or be explicit and type it as (a: number) => number
    let f = (a: number) => {
        console.log('return a:', a);
        return (a: number) => { return a + 1 };
    };
    return f(a);
}

let f = createCallback(1); // (a: number) => number 
on("start", f);