Inicio > Cursos > TypeScript > Generics
TypeScriptTipos AvanzadosLección 7 de 18

Generics

Los generics son como plantillas de tipo. Imagina que quieres una función que devuelva el primer elemento de un array, pero funcione con arrays de cualquier tipo: números, strings, objetos. Sin generics tendrías que escribir una versión por cada tipo, o usar any (perdiendo toda seguridad).

Con generics, defines un "parámetro de tipo" (T) que se resuelve cuando usas la función: el compilador infiere automáticamente qué tipo es T según lo que le pases.

Los constraints (restricciones) con extends limitan qué tipos puede ser T. Por ejemplo, T extends { id: string } garantiza que T siempre tendrá una propiedad id de tipo string, permitiéndote acceder a ella sin errores.

El patrón K extends keyof T es especialmente poderoso: garantiza que K es una clave válida de T, y T[K] devuelve exactamente el tipo de esa propiedad. Los generics son la base de todas las librerías TypeScript populares: useState<T>, Array<T>, Promise<T>.

// Función genérica básica
function primero<T>(arr: T[]): T | undefined {
  return arr[0];
}
const num = primero([1, 2, 3]);      // T = number
const str = primero(["a", "b"]);     // T = string

// Constraints — T debe tener ciertas propiedades
function obtenerPropiedad<T, K extends keyof T>(obj: T, clave: K): T[K] {
  return obj[clave];
}
const nombre = obtenerPropiedad({ nombre: "Ana", edad: 25 }, "nombre"); // string
const edad = obtenerPropiedad({ nombre: "Ana", edad: 25 }, "edad");     // number
// obtenerPropiedad({ nombre: "Ana" }, "email"); // Error: "email" no existe

// Clase genérica
class Pila<T> {
  private items: T[] = [];
  push(item: T): void { this.items.push(item); }
  pop(): T | undefined { return this.items.pop(); }
  peek(): T | undefined { return this.items.at(-1); }
  get size(): number { return this.items.length; }
}

const pilaNumeros = new Pila<number>();
pilaNumeros.push(1); pilaNumeros.push(2);
const top = pilaNumeros.pop(); // number | undefined

// Interface genérica — ApiResponse
interface ApiResponse<T> {
  data: T;
  status: number;
  timestamp: string;
  error?: string;
}

type UsuariosResponse = ApiResponse<Usuario[]>;
type LoginResponse = ApiResponse<{ token: string; expires: number }>;
Consejo🔑 K extends keyof T es uno de los patrones genéricos más útiles. Garantiza que K sea una clave válida de T, y T[K] devuelve exactamente el tipo de esa propiedad.
← Clases en TypeScriptUtility Types →

Practica esta lección

Resuelve los ejercicios del curso de TypeScript en la app, gratis y con corrección automática.

Empezar a practicar