首页 > 解决方案 > 'Function' 类型的参数不能分配给 '(...args: any[]) => void' 类型的参数

问题描述

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 - 错误 TS2345:'Function' 类型的参数不可分配给'(...args: any[]) => void' 类型的参数。
  类型 'Function' 不匹配签名 '(...args: any[]): void'。

22 on1("开始", f);
                ~

如果我删除 , 的Function类型断言createCallbackon1("start", f)那么不是Function表示闭包的通用类型吗?

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

我不明白他为什么会更改Function(...args: any[]) => void使我的代码中断的原因。

标签: typescript

解决方案


有一个建议允许这样的事情,因为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);

推荐阅读