Hola gente!
Bueno, saltemos la introducción (porque no la hay 😅) y vayamos directo a lo que vinimos
↓↓↓
Qué es function overloading ❓
En español (🇪🇸) sería algo asi como "Sobrecarga de funciones" o "Sobrecarga de métodos" 👀
Básicamente es la posibilidad de establecer "diferentes" implementaciones sobre una misma función lo que nos va a permitir realizar diferentes tareas dependiendo de lo que la función reciba como parámetro.
Es decir, con una única función podemos realizar 2 tareas diferentes en lugar de crear una función para cada tarea (2 funciones).
Funcion Overloading 🧙🏻♂️ (magia)
Vamos a ver 2 simples ejemplos, el primero uno que es encuentra en la documentación de TypeScript:
function add(a:string, b:string):string; // Tipamos la función 'add' para que reciba 2 strings y retorne un string
function add(a:number, b:number): number; // Tipamos la función 'add' para que reciba 2 number y retorne un number
function add(a: any, b:any): any { // Tipamos la funcion diciendo que puede recibir 2 any y retornar un any
return a + b;
}
add("Hello ", "Steve"); // returns "Hello Steve"
add(10, 20); // returns 30
Tal como vemos, si le enviamos 2 strings los concatena y si enviamos 2 numbers los suma.
Eso fue un ejemplo demasiado aburrido.
La posta ↓
Vamos con un ejemplo más completo y complejo para entender realmente los beneficios:
Tenemos las siguientes 2 interfaces:
interface HasEmail {
name: string;
email: string;
}
interface HasPhoneNumber {
name: string;
phone: string;
}
Y la siguiente función:
function contactPeople(method: 'email' | 'phone', people: HasEmail | HasPhoneNumber): void {
if (method === 'email') {
console.log('Name: ', (people as HasEmail).name);
console.log('Email: ', (people as HasEmail).email);
} else {
console.log('Name: ', (people as HasPhoneNumber).name);
console.log('Phone: ', (people as HasPhoneNumber).phone);
}
}
Es decir, contactPeople
puede recibir el método 'email' o 'phone' y según eso podemos mostrar por consola su 'name' (no hay problema ya que los 2 tienen name) y su 'email' o su 'phone' según corresponda.
O sea, podemos hacer lo siguiente sin problemas:
// ✅ Email works
contactPeople('email', { name: 'Nahuel', email: '12345678' });
// ✅ Phone works
contactPeople('phone', { name: 'Nahuel', phone: '12345678' });
Bien!
Pero... Que ocurre si hacemos lo siguiente?
// ❌ Mixing: does not work
contactPeople('email', { name: 'Nahuel', phone: '12345678' });
Eso no funcionará a pesar de que typescript no nos arroje ningún error!
Porqué?
Simplemente porque cuando le decimos que de method
tenga email
-> va a ingresar a la primer condición de la función e intentará mostrar su name
y su email
y como verán no le estamos enviando ningún email
, si no que estamos enviando un phone
:
if (method === 'email') {
console.log('Name: ', (people as HasEmail).name);
console.log('Email: ', (people as HasEmail).email);
}
Cual es el problema?
El problema es que eso no va a funcionar y recién nos enteraríamos cuando la aplicación se ejecute!
Necesitamos que Typescipt nos alerte de esto para solucionarlo o para no cometer ese error!
Function overloading al rescate
Acá es cuando entra la magia 🧙🏻♂️
Vamos a agregar las 2 lineas siguientes arriba de la funcion que teníamos declarada:
function contactPeople(method: 'email', people: HasEmail): void;
function contactPeople(method: 'phone', people: HasPhoneNumber): void;
Con eso estamos simplemente tipando la función (si, ya sé que ya estaba tipada, pero con esto estaríamos haciendo un tipado 'más fuerte' que luego nos va a "salvar las papas" 🥔)
Lo que estamos haciendo con eso es simplemente decir:
- Cuando
method===email
->people
será de tipoHasEmail
- Cuando
method===phone
->people
será de tipoHasPhoneNumber
Entonces, si querémos hacer lo siguiente:
// ❌ No overload matches this call
contactPeople('email', { name: 'Nahuel', phone: '12345678' });
Ahora TypeScript nos advierte que no es posible hacer eso!
Fantastico! No?
Learn more 👨🏻🎓
Si querés aprender más de funciones con TypeScript recomiendo leer la siguiente documentación: typescriptlang.org/docs/handbook/functions...
Espero que les haya servido ;)