What is the return type for a function that returns another function

Since this question popped up first in Google for how to type return function for a function that returns a function, I will add the generic solution here for declaring these types.

So if you want to add type declaration to this curried add function:

const add = (a : number) => (b: number) => a + b;

You just duplicate what is after the = sign and make the return value the corresponding value:

export const add: (a : number) => (b: number) => number =
    (a : number) => (b: number) => a + b;

But at this point, you don't need the types for the actual function, so you can just type this, as if it was JS:

export const add: (a : number) => (b: number) => number =
    a => b => a + b;

Writing it more extensively:

const add: (a : number) => (b: number) => number =
    a => {
        console.log(a);
        return b => {
            console.log(b);
            return a + b;
        }
    };

using function:

function add(a: number): (b: number) => number {
    return function(b) {
        return a + b
    }
}

With generics:

export const add: <A extends number, B extends number>(a : A) => (b: B) => number =
    a => b => a + b;

or with function (B extends number can be at the same place as A extends number, depending on usage):

function add<A extends number>(a: A): <B extends number>(b: B) => number {
    return function(b) {
        return a + b
    }
}

If I understood you correctly, your solution will depend on the type that the "second" function returns.

In a nutshell, there are at least 2 ways to do it:

  1. Lambda syntax
  2. Interfaces (normal and generic interfaces)

I've tried to explain all these in the code below, please, check it:

module main
{
    export class TestClass
    {
        // Use lamba syntax as an interface for a return function
        protected returnSpecificFunctionWhichReturnsNumber(): () => number
        {
            return this.specificFunctionWhichReturnsNumber;
        }

        protected specificFunctionWhichReturnsNumber(): number
        {
            return 0;
        }

        // Use an interface to describe a return function
        protected returnSpecificInterfaceFunction(): INumberFunction
        {
            return this.specificFunctionWhichReturnsNumber;
        }

        // Use a generic interface to describe a return function
        protected returnSpecificGenericInterfaceFunction(): IReturnFunction<number>
        {
            return this.specificFunctionWhichReturnsNumber;
        }
    }

    // An interface for a function, which returns a number
    export interface INumberFunction
    {
        (): number;
    }

    // A generic interface for a function, which returns something
    export interface IReturnFunction<ValueType>
    {
        (): ValueType;
    }
}