TypeScript: funciones como parámetros con tipado estricto — análisis completo

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

TypeScript: funciones como parámetros con tipado estricto — análisis completo con ejemplos

\n\n

¡Hola, colega! Si alguna vez has escrito en JavaScript y has pasado una función a otra función (por ejemplo, a setTimeout o Array.map), ya conoces el concepto de funciones de orden superior. Pero cuando se trata de TypeScript, surge una pregunta lógica: "¿Se puede tipificar estrictamente la función que paso como parámetro?". La respuesta es sí, y es una de las características más potentes del lenguaje.

\n\n

En este artículo, analizaremos cómo declarar tipos de funciones en TypeScript, cómo pasarlas como argumentos y cómo no equivocarse con las firmas. Aprenderás a hacer que tu código no solo sea seguro, sino también autodocumentado. ¡Allá vamos!

\n\n

Por cierto, esta pregunta es una de las más populares en Stack Overflow (miles de visitas). Así que si quieres entenderlo de una vez por todas, estás en el lugar correcto.

\n\n

Por qué es importante: el tipado estricto ahorra tiempo

\n\n

Imagina que escribes una función que recibe otra función (callback). Sin tipos, podrías pasar accidentalmente una función con un número incorrecto de argumentos o un valor de retorno incorrecto. TypeScript detecta estos errores en tiempo de compilación, no en tiempo de ejecución. Es como un seguro para tu código.

\n\n

Aquí tienes un ejemplo que no funcionará sin tipos:

\n\n
// JavaScript (sin tipos) — el error solo aparecerá en tiempo de ejecución\nfunction processData(callback) {\n    const result = callback(10, 20);\n    console.log(result);\n}\n\n// Ups, pasamos una función con un solo parámetro\nprocessData((x) => x * 2); // NaN — porque el segundo parámetro es undefined
\n\n

Con TypeScript podemos indicar explícitamente qué firma espera el callback:

\n\n
// TypeScript — error en tiempo de compilación\nfunction processData(callback: (a: number, b: number) => number): void {\n    const result = callback(10, 20);\n    console.log(result);\n}\n\n// ✅ Correcto\nprocessData((x, y) => x + y); // 30\n\n// ❌ Error: El tipo '(x: number) => number' no se puede asignar al tipo '(a: number, b: number) => number'\n// processData((x) => x * 2);
\n\n

Genial, ¿verdad? Ahora analicemos todas las formas de declarar estos tipos.

\n\n

Forma 1: Firma en línea (la más sencilla)

\n\n

La forma más directa es especificar la firma de la función directamente en los parámetros. Es útil cuando la función parámetro se usa solo una vez.

\n\n
// Función que recibe otra función con dos números y devuelve un string\nfunction formatNumbers(\n    a: number,\n    b: number,\n    formatter: (x: number, y: number) => string\n): string {\n    return formatter(a, b);\n}\n\n// Uso\nconst result = formatNumbers(5, 10, (x, y) => `Suma: ${x + y}`);\nconsole.log(result); // "Suma: 15"
\n\n

Ventajas: rápido, claro.
\nDesventajas: si la firma se repite, tendrás que duplicar el código.

\n\n

Forma 2: Alias de tipo para la función (reutilizable)

\n\n

Si usas la misma firma en varios lugares, es mejor definirla como un alias de tipo. Esto hace que el código sea más limpio y fácil de mantener.

\n\n
// Declaramos el tipo de función\ntype Callback = (error: Error | null, data: string) => void;\n\n// Función que recibe un Callback\nfunction fetchData(url: string, callback: Callback): void {\n    // Simulación de una solicitud asíncrona\n    setTimeout(() => {\n        if (url) {\n            callback(null, "Datos recibidos");\n        } else {\n            callback(new Error("URL vacía"), "");\n        }\n    }, 1000);\n}\n\n// Uso\nfetchData("/api/data", (err, data) => {\n    if (err) {\n        console.error("Error:", err.message);\n    } else {\n        console.log("Éxito:", data);\n    }\n});
\n\n

Observa que usamos void como tipo de retorno. Esto significa que la función puede no devolver nada.

Blogs

Book Recommendations