Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Argument of type 'Function' is not assignable to parameter of type '(...args: any[]) => void'

Tags:

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);

In the above code, on("start", f) works fine but on1("start", f); returns error

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);
                ~

If I remove the Function type assertion of createCallback, on1("start", f) works, isn't Function a general type to represent closures?

The original question comes from this commit, https://github.com/DefinitelyTyped/DefinitelyTyped/commit/96545154cc6488643a7064a6dc4ec9726c7af12a#diff-7d84e08967cded0b99ed4328aab0a1a8L291

I don't understand why he changes Function to (...args: any[]) => void which makes my code break.

like image 320
Joey Avatar asked Aug 08 '18 10:08

Joey


People also ask

Is not assignable to parameter of type function?

The error message "Argument of type 'void' is not assignable to parameter of type" means that we are passing an argument of type void to a function that expects a parameter of a different type. To solve the error, make sure to return a value from your functions.

Is not assignable to type '() => void?

The "Type 'void' is not assignable to type" TypeScript error occurs when we forget to return a value from a function, so the function gets an implicit return type of void . To solve the error, make sure you return a value of the correct type from your functions before the assignment.

What is not assignable to parameter of type promise unknown?

The "Type 'Promise' is not assignable to type" TypeScript error occurs when we try to assign a value that has a type of Promise to a value that has an incompatible type. To solve the error, resolve the Promise and make the two values of compatible types before the assignment.


1 Answers

There is a suggestion to allow something like this, for Function to be assignable to (...args: any[]) => any. The reason that this is not the current behavior is:

The original intention of Function is to not be callable. in other words, Function to function types should be like unknown to other types, but not callable. we have since relaxed this restriction giving Function a callable behavior in the compiler through special casing. We have talked about making this a --noImplicitAny error since, it is really unsafe to call Functions.

I suggest you up-vote the suggestion if this is important to you.

I would generally stay way from Function it's not a type-safe away to express function signatures. For your case I would use the following:

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);
like image 111
Titian Cernicova-Dragomir Avatar answered Sep 22 '22 23:09

Titian Cernicova-Dragomir