Búsqueda de sitios web

typescript - Cómo sobrecargar una función de JavaScript que está definida en un objeto


He definido algunas funciones en este objeto dentro de una función calculator porque quiero encadenarlas. Mi objetivo es sobrecargar la función addNumber, pero parece que no logro que la sintaxis sea correcta.

A continuación se muestra un ejemplo de lo que quiero lograr (no funcionará porque la sintaxis es incorrecta)

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

Este fue el ejemplo que me dio la idea, sin embargo, la función está definida normalmente. ¿Cuáles son algunas formas en que puedo sobrecargar una función que está definida en un objeto?

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

Respuesta #1

Si estás dispuesto a cambiar a una clase anónima, entonces es bastante sencillo lograr la sobrecarga:

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

Enlace del parque

Los métodos literales de objetos y las expresiones de función no admiten sobrecarga. La única otra opción es usar una expresión de función con una afirmación de tipo:

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

Enlace del parque

Respuesta #2

(() => {
  //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...