2

I've defined some functions in this object inside a function calculator because I want to chain them. My goal is to to overload the addNumber function but I can't seem to get the syntax right.

Below is an example of what I want to achieve (won't work because syntax is wrong)

const calculator = () => {
    return {
        result: 0,
        addNumber(a: number) : number;
        addNumber(a: number | b: number): number;
        addNumber(a: number | b: string): number {
            // Implementation to add numbers depending on function overload
            return this;
        },

        multiplyNumber(a) {
            this.result = this.result * a;
            return this;
        },

        log() {
             console.log(this.result);
        }
    };
}

// logs 10
calculator().addNumber(10).log();

// logs 25
calculator().addNumber(10,15).log();

// logs 25
calculator().addNumber(10,'15').log();

This is was the example that gave me the idea however, the function is defined normally. What are some ways I can overload a function that is defined in object?

function makeDate(timestamp: number): Date;
function makeDate(m: number, d: number, y: number): Date;
function makeDate(mOrTimestamp: number, d?: number, y?: number): Date {
  if (d !== undefined && y !== undefined) {
    return new Date(y, mOrTimestamp, d);
  } else {
    return new Date(mOrTimestamp);
  }
}
const d1 = makeDate(12345678);
const d2 = makeDate(5, 5, 5);
const d3 = makeDate(1, 3);
2
  • function overloading is not a thing in JavaScript. Your function will have to check which version has been called either by checking types or number of arguments. Commented Aug 3, 2022 at 9:03
  • @phuzi function signature overloading is a thing in TS. The question is how to do that in an object literal Commented Aug 3, 2022 at 9:09

2 Answers 2

2

If you are willing to switch to an anonymous class, then it's pretty simple to get overloading:

const calculator = () => {
    return new class {
        result = 0;

        addNumber(a: number) : this
        addNumber(a: number, b: number): this
        addNumber(a: number, b: string): this
        addNumber(a: number, b?: number | string): this {
            // Implementation to add numbers depending on function overload
            return this;
        }

        multiplyNumber(a: number) {
            this.result = this.result * a;
            return this;
        }

        log() {
             console.log(this.result);
        }
    };
}

Playground Link

Object literal methods and function expressions don't support overloading. The only other option is to use a function expression with a type assertion:

const calculator = () => {
    return {
        result: 0,

        addNumber : function (a: number, b?: number | string) {
            return this;
        } as {
            <T>(this: T, a: number) : T
            <T>(this: T, a: number, b: number): T
            <T>(this: T, a: number, b: string): T
        }
    };
}

Playground Link

Sign up to request clarification or add additional context in comments.

Comments

0

(() => {
  //array that store functions
    var Funcs = []
     /**
     * @param {function} f overload function
     * @param {string} fname overload function name
   * @param {parameters} vtypes function parameters type descriptor (number,string,object....etc
     */
    overloadFunction = function(f, fname, ...vtypes) {
        var k,l, n = false;
        if (!Funcs.hasOwnProperty(fname)) Funcs[fname] = [];
        Funcs[fname].push([f, vtypes?vtypes: 0 ]);
        window[fname] = function() {
            for (k = 0; k < Funcs[fname].length; k++)
                if (arguments.length == Funcs[fname][k][0].length) {
                    n=true;
                    if (Funcs[fname][k][1]!=0)
                    for(i=0;i<arguments.length;i++)
                    {
                        if(typeof arguments[i]!=Funcs[fname][k][1][i])
                        {
                            n=false;
                        }
                    }
                    if(n) return Funcs[fname][k][0].apply(this, arguments);
                }
        }
    }
})();

//First sum function definition with parameter type descriptors
overloadFunction(function(a,b){return a+b},"sum","number","number")
//Second sum function definition with parameter with parameter type descriptors
overloadFunction(function(a,b){return a+" "+b},"sum","string","string")
//Third sum function definition (not need parameter type descriptors,because no other functions with the same number of parameters
overloadFunction(function(a,b,c){return a+b+c},"sum")

//call first function
console.log(sum(4,2));//return 6
//call second function
console.log(sum("4","2"));//return "4 2"
//call third function
console.log(sum(3,2,5));//return 10
//ETC...

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.