TypeScript de Cero a Experto / Funciones e interfaces
Sobrecargas: una función, varias firmas
A veces una función se comporta —y tipa— distinto según cómo la llames: pásale un número y devuelve un número; pásale un array y devuelve un array. Las SOBRECARGAS te dejan darle varias firmas públicas a una sola función. Es una técnica de nicho pero elegante; hoy la conoces y aprendes cuándo hay algo mejor.
El empleado que atiende varias ventanillas
Declarar sobrecargas
Escribes las firmas públicas ANTES de la función, y luego UNA implementación que las cumple todas:
// las FIRMAS públicas (lo que ve quien la usa):
function duplicar(valor: number): number;
function duplicar(valor: string): string;
// la IMPLEMENTACIÓN (oculta para quien llama; debe cubrir todos los casos):
function duplicar(valor: number | string): number | string {
if (typeof valor === "number") return valor * 2;
return valor + valor;
}
// gracias a las firmas, TS sabe el tipo EXACTO de retorno según lo que pases:
const n = duplicar(5); // TS: number (no number | string)
const s = duplicar("ab"); // TS: string
n.toFixed(2); // ✓ TS sabe que n es number
s.toUpperCase(); // ✓ TS sabe que s es stringLo valioso: sin sobrecargas, duplicar devolvería number | string siempre, y
tendrías que estrechar el resultado cada vez. Con ellas, TS sabe que
duplicar(5) devuelve EXACTAMENTE number —el retorno preciso según la entrada.
Las dos primeras líneas son las ventanillas públicas; la tercera es el empleado
que las resuelve por dentro.
La firma de implementación es privada
Cuándo sobrecargar… y cuándo no
Las sobrecargas son poderosas pero a menudo hay algo más simple:
// ❌ sobrecarga innecesaria: si el retorno NO cambia según la entrada,
// una simple unión basta y es más clara:
function longitud(x: string | any[]): number {
return x.length; // sin overloads: el retorno siempre es number
}
// ✅ sobrecarga justificada: el TIPO DE RETORNO depende del de entrada
// (number→number, string→string) — eso una unión sola no lo captura bien.
// para transformaciones genéricas, un GENÉRICO (módulo 5) suele ganar:
function primero<T>(arr: T[]): T | undefined {
return arr[0]; // funciona para cualquier tipo, sin repetir firmas
}Ese ejemplo es real: así es como TypeScript tipa document.createElement —con
sobrecargas—, para que createElement("a") te dé un HTMLAnchorElement con
.href y createElement("img") un HTMLImageElement con .src. Cuando veas ese
autocompletado preciso según el tag, ya sabes qué hay detrás.
Tienes function envolver<T>(x: T): T[] { return [x]; } que mete cualquier valor en un array. ¿Deberías convertirla en sobrecargas (una por tipo)?
Mini-reto
Distingue las herramientas: 1) escribe una sobrecarga JUSTIFICADA —function convertir(x: string): number y function convertir(x: number): string— con su
implementación (string→Number(x), number→String(x)); 2) comprueba que
convertir("42") tipa como number y convertir(42) como string; 3)
reflexiona: ¿podría un genérico hacer esto? (No: el retorno es el OPUESTO de la
entrada, justo el caso donde las sobrecargas ganan.)
Qué sigue
Cierras el módulo con un reto que junta funciones tipadas, un callback y una interface trabajando en equipo. Luego, el módulo 4 aborda la técnica más característica de TypeScript: el NARROWING —enseñarle al compilador a razonar sobre tus datos como lo haces tú.