La sobrecarga de funciones permite declarar varias versiones de una función con diferentes parámetros y tipos de retorno. Cada versión de la función (o firma) se llama sobrecarga.
La implementación real de la función debe manejar todas las combinaciones de parámetros definidos en las sobrecargas.
Sintaxis básica de sobrecarga de funciones
Para crear sobrecargas de funciones en TypeScript debemos hacer lo siguiente
- Definir las firmas de las funciones sobrecargadas.
- Proveer una única implementación de la función que maneje todas las combinaciones de parámetros.
Por ejemplo
// Definición de sobrecargas
function miFuncion(param: string): string;
function miFuncion(param: number): number;
// Implementación de la función
function miFuncion(param: string | number): string | number {
// hacer cosas
return "";
}
En este ejemplo, la función miFuncion
tiene dos firmas: una que acepta un string
y otra que acepta un number
. La implementación de la función maneja ambas firmas.
Si intentamos llamar a la función con un tipo, o una cantidad de parámetros que no están admitidas por las firmas, por ejemplo
miFuncion(12); // esto no da error
miFuncion("12") // esto no da error
let miObjeto = {};
miFuncion(miObjeto); // esto da un error, no admite un objeto
miFuncion(12, 12); // esto da un error, no admite dos int
Recibiremos un error del compilador o del IDE, como el siguiente:
The call would have succeeded against this implementation, but implementation signatures of overloads are not externally visible.
Es decir, cuando existen firmas sobrecargadas de una función, TypeScript convierte la función que define el objeto en privada. Por tanto no podemos usarla directamente, y debemos usar obligatoriamente una de sus firmas definidas
Sobrecarga con diferentes tipos de parámetros
Imaginemos una función que puede sumar dos números o concatenar dos cadenas. Podemos usar sobrecarga para definir ambas operaciones.
// Definición de sobrecargas
function combinar(a: string, b: string): string;
function combinar(a: number, b: number): number;
// Implementación de la función
function combinar(a: string | number, b: string | number): string | number {
if (typeof a === "string" && typeof b === "string") {
return a + b;
} else if (typeof a === "number" && typeof b === "number") {
return a + b;
}
throw new Error("Tipos de parámetros no coinciden");
}
console.log(combinar("Hola, ", "mundo")); // "Hola, mundo"
console.log(combinar(5, 10)); // 15
Observar cómo la implementación de combinar
admite tanto string
como number
como parámetros, para cumplir con ambas definiciones.
Alternativamente, podríamos haber usado any
. Aunque en la medida de lo posible, por limpieza, es mejor que especifiquemos los tipos
Sobrecarga con diferentes cantidades de parámetros
También es posible sobrecargar funciones con diferentes cantidades de parámetros. Por ejemplo, una función que puede tomar uno o dos parámetros:
// Definición de sobrecargas
function mostrarMensaje(mensaje: string): void;
function mostrarMensaje(mensaje: string, veces: number): void;
// Implementación de la función
function mostrarMensaje(mensaje: string, veces?: number): void {
if (veces === undefined) {
console.log(mensaje);
} else {
for (let i = 0; i < veces; i++) {
console.log(mensaje);
}
}
}
mostrarMensaje("Hola"); // "Hola"
mostrarMensaje("Hola", 3); // "Hola" "Hola" "Hola"
En este ejemplo, veces
es un parámetro opcional que permite a la función mostrarMensaje
manejar uno o dos argumentos.