Translate

martes, 12 de agosto de 2025

Sobrecarga de métodos en TypeScript: limitaciones y soluciones


A diferencia de lenguajes como Java o C#, TypeScript sí permite declarar sobrecargas… pero con una particularidad: solo podemos implementar un único método que soporte todas las variantes declaradas.

Esto significa que no podemos tener múltiples implementaciones distintas como en otros lenguajes, sino que debemos manejar la lógica dentro de un único cuerpo de función.

Supongamos que queremos una función procesar que:

  • Si recibe un string, lo devuelva en mayúsculas.
  • Si recibe un number, devuelva su cuadrado.
  • Si recibe dos number, devuelva su suma.


En Java o C# esto serían tres métodos distintos.

En TypeScript lo declaramos así:


class Procesador {

  procesar(dato: string): string;

  procesar(dato: number): number;

  procesar(a: number, b: number): number;


  // Implementación única obligatoria

  procesar(arg1: string | number, arg2?: number): string | number {

    if (typeof arg1 === 'string') {

      return arg1.toUpperCase();

    }

    if (typeof arg1 === 'number' && typeof arg2 === 'number') {

      return arg1 + arg2;

    }

    if (typeof arg1 === 'number') {

      return arg1 * arg1;

    }

    throw new Error('Parámetros no soportados');

  }

}


const p = new Procesador();

console.log(p.procesar('hola'));    // "HOLA"

console.log(p.procesar(5));         // 25

console.log(p.procesar(3, 4));      // 7


En otros lenguajes, cada sobrecarga tiene su propio cuerpo.

En TypeScript, todas las sobrecargas deben compartir una única implementación que maneje la lógica de todos los casos.

¿Cómo simular implementaciones separadas?  Una opción para acercarnos al comportamiento tradicional es delegar la lógica a métodos privados:


class ProcesadorSeparado {

  procesar(dato: string): string;

  procesar(dato: number): number;

  procesar(a: number, b: number): number;


  procesar(arg1: string | number, arg2?: number): string | number {

    if (typeof arg1 === 'string') return this.procesarString(arg1);

    if (typeof arg1 === 'number' && typeof arg2 === 'number') return this.procesarDosNumeros(arg1, arg2);

    if (typeof arg1 === 'number') return this.procesarUnNumero(arg1);

    throw new Error('Parámetros no soportados');

  }


  private procesarString(valor: string): string {

    return valor.toUpperCase();

  }


  private procesarUnNumero(valor: number): number {

    return valor * valor;

  }


  private procesarDosNumeros(a: number, b: number): number {

    return a + b;

  }

}


const p2 = new ProcesadorSeparado();

console.log(p2.procesar('hola')); // "HOLA"

console.log(p2.procesar(5));      // 25

console.log(p2.procesar(3, 4));   // 7



Esto no elimina la restricción del lenguaje, pero hace que el código sea más limpio y cercano al estilo de sobrecarga en otros lenguajes.