tallsamurai
tallsamurai

Reputation: 21

Typescript call signature on function as argument

I am trying to build a function defaultArguments which takes an existing function and changes its default arguments with new inputs.

var add = function (a: number, b: number) {
    return a + b;
};

var defaultArguments = function(
    // func: (args: ReturnType<typeof func.arguments>) => void, 
    func: Function,
    obj: Object) {
    let keys = Object.keys(obj);
    let alphabeth = "abcdefghijklmnopqrstuvwxyz";

    if (typeof func === "function") {
        for (let i: number = 0; i < func.arguments.length; i++) {
            for (let a = 0; a < keys.length; a++) {
                // Replace arguments according to alphabethic order
                let arr = [];
                arr.splice(alphabeth.indexOf(keys[a]), 0, keys[a]); // push value to position of letter in 'alphabeth'
                func.arguments[a] = arr[a];
            }
        }
        return func;

    } else { return "Cannot find function " + func['name'] };
};

const add2 = defaultArguments(add, { b: 9 });
console.assert(add2(10) === 19);
console.assert(add2(10, 7) === 17);
console.assert(isNaN(add2()));

When calling the second command console.assert(add2(10) === 19) it gives me the following error:

Cannot invoke an expression whose type lacks a call signature. Type 'string | Function' has no compatible call signatures

As if the ReturnType of const add2 = defaultArguments(add, { b: 9 }) is not a function of a string.

Upvotes: 1

Views: 760

Answers (1)

Andrew Shepherd
Andrew Shepherd

Reputation: 45222

As @jcalz points out in the comment, the method defaultArguments either returns a function or a string.

At the point where you write the code...

console.assert(add2(10) === 19);

the compiler quite rightly flags an error, because at this point you do not know which of the two possible types add2 is.

If you add an additional type check to your code, the compiler will be assured you are working with a value of type function, and will compile without an error.

if (typeof(add2) === 'function')) {
  console.assert(add2(10) === 19);
  console.assert(add2(10, 7) === 17);
  console.assert(isNaN(add2()));
} else {
  console.error(add2);
}

Upvotes: 1

Related Questions