Múltiples genéricos y buenas prácticas

Mucha gente tiene problemas para entender o utilizar los genéricos porque comete el error de darle a su genérico nombres compuestos por una única letra, como K, V o T. Esto es un error, y en este vídeo, trato de explicarte que en TypeScript un genérico puede ser un identificador con todas las letras que necesites, algo que hará tu código más sencillo de mantener.

Cuando trabajamos con TypeScript, los genéricos son una herramienta fundamental para escribir código flexible y reutilizable. Pero, ¿qué ocurre cuando necesitamos manejar más de un genérico a la vez? Podemos declarar múltiples genéricos en una función, tipo o interfaz, separándolos por comas, de forma muy similar a cómo declaramos los parámetros de una función.

Por ejemplo, imaginemos que tenemos un tipo Respuesta que depende de dos genéricos: uno para un mensaje y otro para un valor adicional. Podríamos declararlo así:

type Respuesta<Mensaje, Extra> = {
  mensaje: Mensaje;
  extra?: Extra;
};

Al usar este tipo, debemos especificar ambos genéricos en el orden correcto, por ejemplo:

const respuesta1: Respuesta<string, number> = {
  mensaje: "Hola",
  extra: 42,
};

const respuesta2: Respuesta<boolean, object> = {
  mensaje: true,
  extra: { clave: "valor" },
};

Es importante recordar que el orden en que declaramos los genéricos importa, ya que al usarlos debemos respetar ese orden para que TypeScript asigne correctamente los tipos. Esto puede ser fuente de errores si no prestamos atención.

Un aspecto que suele pasar desapercibido es la elección de los nombres para los genéricos. Muchos cursos y ejemplos usan letras como T, U, X o K para nombrarlos, pero esto puede dificultar la comprensión del código, especialmente cuando hay varios genéricos involucrados. En TypeScript no hay ninguna restricción para usar nombres más descriptivos, y hacerlo mejora mucho la legibilidad.

Volviendo al ejemplo anterior, en lugar de usar T y U, podemos usar nombres como Mensaje y Extra, que nos indican claramente qué representa cada genérico. Esto facilita entender el código tanto para quien lo escribe como para quien lo lee después.

Esta práctica es especialmente relevante cuando trabajamos con librerías como React o Redux, donde los genéricos son omnipresentes. Por ejemplo, en React, al definir componentes genéricos, es común que las props se pasen como un genérico. Usar nombres descriptivos para estos genéricos ayuda a que el código sea más claro y mantenible.

De manera similar, en sistemas de acciones para Redux, es preferible nombrar los genéricos con términos que reflejen su propósito en lugar de letras arbitrarias. Esto hace que la API sea más amigable y comprensible.

Lamentablemente, no todas las librerías siguen esta buena práctica. Algunas, como ciertas implementaciones de Saga, utilizan letras genéricas sin significado, lo que puede complicar la lectura y el mantenimiento del código. Por eso, si estamos diseñando nuestras propias APIs o librerías, debemos esforzarnos por usar nombres descriptivos en los genéricos.

En definitiva, cuando trabajamos con múltiples genéricos en TypeScript, es fundamental no solo saber cómo declararlos correctamente, sino también elegir nombres que aporten claridad. Esto nos ahorrará confusiones y facilitará la colaboración con otros desarrolladores, además de mejorar nuestra propia experiencia al revisar el código en el futuro.

Lista de reproducción
  1. 1
    Temporada 1
    5 minutos
  2. 2
    ¿Qué es TypeScript?
    11 minutos
  3. 3
    Instalando TypeScript
    8 minutos
  4. 4
    Compilando un Hola Mundo sencillo
    7 minutos
  5. 5
    Hola Mundo pero con tipos
    10 minutos
  6. 6
    Tipos: tipos primitivos
    12 minutos
  7. 7
    Tipos: tipos especiales (any, null, ...)
    10 minutos
  8. 8
    Tipos: arrays y tuplas
    11 minutos
  9. 9
    Tipos: objetos
    7 minutos
  10. 10
    Funciones: lo básico
    9 minutos
  11. 11
    Funciones: tipando funciones
    9 minutos
  12. 12
    Clases: introducción a las clases
    9 minutos
  13. 13
    Clases: creando una clase
    10 minutos
  14. 14
    Clases: modificador private
    8 minutos
  15. 15
    Clases: modificador readonly
    3 minutos
  16. 16
    Clases: Atributos virtuales con getters y setters
    10 minutos
  17. 17
    Clases: herencia
    9 minutos
  18. 18
    Clases: modificadores abstract y protected
    8 minutos
  19. 19
    Tipos alias
    6 minutos
  20. 20
    Tipos literales
    5 minutos
  21. 21
    Uniones de tipos
    7 minutos
  22. 22
    Uniones discriminantes
    7 minutos
  23. 23
    Intersecciones de tipos
    5 minutos
  24. 24
    Interfaces: introducción
    7 minutos
  25. 25
    Interfaces: modificadores y funciones
    9 minutos
  26. 26
    Interfaces: usándolas con clases
    8 minutos
  27. 27
    Interfaces: herencia de interfaces
    8 minutos
  28. 28
    Interfaces: interfaces indizadas
    5 minutos
  29. 29
    Interfaces: funciones y tipos híbridos
    5 minutos
  30. 30
    ¿Qué diferencia hay entre interfaces y tipos? (2020)
    8 minutos
  31. 31
    Casteos con as
    6 minutos
  32. 32
    instanceof y las guardas
    9 minutos
  33. 33
    Tipos enumerados
    8 minutos
  34. 34
    Valores avanzados para enumerados
    7 minutos
  35. 35
    Enumerados con valores computados
    6 minutos
  36. 36
    Genéricos en tipos
    8 minutos
  37. 37
    Múltiples genéricos y buenas prácticas
    5 minutos
  38. 38
    Genéricos en funciones
    8 minutos
  39. 39
    Genéricos con restricciones
    6 minutos
  40. 40
    Tipos de utilidad
    3 minutos
  41. 41
    Exportando módulos
    9 minutos
  42. 42
    Importando módulos
    7 minutos
  43. 43
    Export default e import asterisco
    6 minutos
  44. 44
    tsconfig
    7 minutos
  45. 45
    Módulos desde NPM
    7 minutos
  46. 46
    Arroba types y los .d.ts
    8 minutos
  47. 47
    Ejemplo (1): creando una API REST simple en TypeScript
    11 minutos
  48. 48
    Ejemplo (2): montando un servidor Express
    8 minutos
  49. 49
    Ejemplo (3): haciendo las funciones de control de datos
    11 minutos
  50. 50
    Ejemplo (4): conectando todas las piezas
    7 minutos