Generics en JavaScript: para qué sirven y cómo usarlos para principiantes

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

¿Qué son los Generics en JavaScript y para qué sirven?

\n\n

Imagina que escribes una función que debe funcionar con diferentes tipos de datos: números, cadenas, objetos. Sin Generics (genéricos) tendrías que duplicar el código o usar any, perdiendo el control sobre los tipos. Los Generics son un mecanismo que permite crear componentes (funciones, clases, interfaces) que funcionan con cualquier tipo de dato, pero manteniendo la información sobre el tipo.

\n\n

Aunque JavaScript es un lenguaje de tipado dinámico, en el ecosistema Node.js se usa activamente TypeScript, que añade tipado estático. Es en TypeScript donde los genéricos se despliegan en todo su potencial. Sin embargo, entender sus principios es útil también para JavaScript puro, especialmente si escribes librerías o trabajas con frameworks modernos.

\n\n

En este artículo veremos:

\n
    \n
  • Para qué sirven los Generics
  • \n
  • Cómo declarar y usar genéricos en TypeScript
  • \n
  • Ejemplos para Node.js (API, procesamiento de datos)
  • \n
  • Limitaciones y mejores prácticas
  • \n
\n\n

Fundamentos de Generics: sintaxis y ejemplos básicos

\n\n

Primer genérico: la función identity

\n\n

El ejemplo clásico es una función que devuelve lo que recibe como entrada:

\n\n
// Sin Generics\nfunction identity(value: any): any {\n  return value;\n}\n\n// Con Generics\nfunction identity<T>(value: T): T {\n  return value;\n}\n\n// Uso\nconst num = identity<number>(42);    // num — number\nconst str = identity<string>('hola'); // str — string\n
\n\n

El símbolo <T> es un parámetro de tipo. Puedes llamarlo como quieras (T, U, Item), pero la tradición dicta usar T (de Type).

\n\n

Genéricos con múltiples parámetros

\n\n

A veces es necesario trabajar con varios tipos simultáneamente:

\n\n
function pair<T, U>(first: T, second: U): [T, U] {\n  return [first, second];\n}\n\nconst result = pair<number, string>(1, 'uno');\n// result: [number, string]\n
\n\n

Genéricos en funciones flecha (Node.js)

\n\n

En React o utilidades se usan a menudo funciones flecha con genéricos:

\n\n
const wrapInArray = <T>(item: T): T[] => {\n  return [item];\n};\n\nconst arr = wrapInArray('prueba'); // arr: string[]\n
\n\n

Aplicación de Generics en proyectos reales de Node.js

\n\n

Manejadores de API con respuestas tipadas

\n\n

Imagina que escribes una función universal para peticiones a una API. Sin genéricos perderías los tipos de datos:

\n\n
// Malo: any\nasync function fetchData(url: string): Promise<any> {\n  const response = await fetch(url);\n  return response.json();\n}\n\n// Bueno: Generics\nasync function fetchData<T>(url: string): Promise<T> {\n  const response = await fetch(url);\n  return response.json();\n}\n\n// Uso\ninterface User {\n  id: number;\n  name: string;\n}\n\nconst user = await fetchData<User>('/api/user/1');\nconsole.log(user.name); // TypeScript sabe que name es string\n
\n\n

Colecciones de datos tipadas

\n\n

Al trabajar con bases de datos (por ejemplo, con Prisma o Mongoose), los genéricos ayudan a crear repositorios universales:

\n\n
class Repository<T extends { id: number }> {\n  private items: T[] = [];\n\n  add(item: T): void {\n    this.items.push(item);\n  }\n\n  getById(id: number): T | undefined {\n    return this.items.find(item => item.id === id);\n  }\n}\n\n// Uso\ninterface Product {\n  id: number;\n  title: string;\n  price: number;\n}\n\nconst productRepo = new Repository<Product>();\nproductRepo.add({ id: 1, title: 'Laptop', price: 1000 });\nconst laptop = productRepo.getById(1);\n
\n\n

Envoltorios para manejo de errores

\n\n

Función universal para

Blogs

Book Recommendations