Reputation: 6347
In the following snippet of code where I have declared a curried add method.
const add = (a: number) => {
return (b?: number) => {
return (b === undefined ? a : add(a + b))
}
}
This works fine if I call this with the following arguments:
add(1)()
But typescript throws the following error when I call it like this:
add(1)(2)()
Cannot invoke an expression whose type lacks a call signature. Type 'number | ((b?: number) => number | ...)' has no compatible call signatures.
What do I need to add to enable typed usage of this method?
Upvotes: 0
Views: 128
Reputation: 330571
I would describe the type of add()
as the following Add
type:
type Add = (a: number) => Add2;
type Add2 = ((b: number) => Add2) & (() => number);
The Add
function type takes a number and returns an Add2
.
The Add2
function type is an overloaded function which returns a different type depending on the number and type of arguments that come in. It's also self-referential: if you call an Add2
with a number
parameter, you get an Add2
out.
You more or less need to use assertions to convince the compiler that your add()
is a valid Add
:
const add = ((a: number) => (b?: number) =>
b === undefined ? a : add(a + b)) as Add;
And then you should be able to use it as expected:
const x = add(1)(2)(3)(); // number
console.log(x); // 6
Okay, hope that helps; good luck!
Upvotes: 2