Con la sobrecarga de funciones definimos diferentes firmas de una función en la que cada firma puede manejar cierto tipado de entrada y salida. TypeScript decidirá de manera automática qué firma es la correcta para usar basándose en los argumentos enviados y el tipo de datos de estos.
Un problema que puede resolver la sobrecarga de funciones
Imaginemos que deseamos implementar una función que devuelva un string
en el caso de que le envíes un array o que devuelva un array en caso de que le mandes un string
como argumento:
// 1️⃣Si le enviamos un array, nos debe unir cada elemento del array y devolver un string.
// 2️⃣Si le enviamos un string, nos debe separar cada caracter y formar un array como respuesta.
// [N,i,c,o] => 'Nico' ... string[] => string 1️⃣
// 'Nico' => [N,i,c,o] ... string => string[] 2️⃣
function parseStr(input: string | string[]): string | string[] {
if (Array.isArray(input)) {
return input.join(''); // string
} else {
return input.split(''); // string[]
}
}
// Llamando a la función...
const rptaArray = parseStr('Nico'); // Entrada: string - Salida: Array
console.log('rptaArray', 'Nico =>' ,rptaArray);
const rptaStr = parseStr(['N','i','c','o']); // Entrada: array - Salida: string
console.log('rptaStr', "['N','i','c','o'] =>",rptaStr);
Definimos la función con un parámetro que puede ser del tipo string
o string[]
(un array que contiene valores de tipo string
) y un retorno que puede ser de igual manera string
o string[]
.
Cuando invocamos la función para enviar los argumentos que deseamos probar, TypeScript no sabe inicialmente qué tipo de dato le estás mandando de manera específica en el código. Por tanto, no podemos acceder en la siguiente línea de código a ningún método propio de un string
o un array:
const rptaArray = parseStr('Nico');
rptaArray.reverse();
const rptaStr = parseStr(['N','i','c','o']);
rptaStr.toLowerCase();
Solución con validación de tipos
Una posible solución es realizar una pequeña validación de tipos previo a querer ejecutar algún método propio del tipo de dato correspondiente:
const rptaArray = parseStr('Nico');
if (Array.isArray(rtaArray)) {
rtaArray.reverse();
}
console.log('rtaArray', 'Nico =>' ,rtaArray);
const rtaStr = parseStr(['N','i','c','o']);
if (typeof rtaStr === 'string') {
rtaStr.toLowerCase();
}
console.log('rtaStr', "['N','i','c','o'] =>",rtaStr);
Solución con sobrecarga de funciones
Para resolver este problema con sobrecarga de funciones debemos declarar 2 firmas adicionales con el mismo nombre de la función: una firma manejará el tipado de entrada/salida como string
/string[]
y la otra forma de manera viceversa, es decir string[]
/string
. El parámetro de la función que tendrá la lógica puede manejar el tipado unknown
, pues ya estamos dejando declarado previamente los tipados de entrada y salida que manejará la función:
function parseStr(input: string): string[];
function parseStr(input: string[]): string;
function parseStr(input: unknown): unknown
Ahora en la función principal haremos una validación de tipos y según ello retornaremos las respuestas respectivas a lo que se busca como output:
// SOBRECARGAS:
function parseStr(input: string): string[]; // Entrada: string - Salida: string[]
function parseStr(input: string[]): string; // Entrada: string[] - Salida: string
// Función principal y a la que se le aplicarán las sobrecargas:
function parseStr(input: unknown): unknown {
if (Array.isArray(input)) {
return input.join(''); // string
} else {
return input.split(''); // string[]
}
}
Finalmente, ya podríamos utilizar los métodos según el tipo de dato de la respuesta obtenida de la función:
function parseStr(input: string): string[]; // Entrada: string - Salida: string[]
function parseStr(input: string[]): string; // Entrada: string[] - Salida: string
function parseStr(input: unknown): unknown {
if (Array.isArray(input)) {
return input.join('');
} else {
return input.split('');
}
}
const rtaArray = parseStr('Nico');
rtaArray.reverse();
console.log('rtaArray', 'Nico =>' ,rtaArray);
const rtaStr = parseStr(['N','i','c','o']);
rtaStr.toLowerCase();
console.log('rtaStr', "['N','i','c','o'] =>",rtaStr);
Contribución creada por: Martín Álvarez (Platzi Contributor).
¿Quieres ver más aportes, preguntas y respuestas de la comunidad?