Generics (tipos genéricos) permiten escribir código universal que funciona con diferentes tipos, manteniendo la estricta seguridad de tipos.
Sintaxis de uso:
function identity<T>(value: T): T { return value; } const x = identity<string>('test'); // T = string
Dónde se aplican:
Ejemplo con restricción de tipo:
function getFirst<T extends { length: number }>(arr: T): T { return arr[0]; }
Pregunta: ¿Es obligatorio especificar un tipo concreto al llamar a una función con un parámetro Genérico?
Respuesta:
No es obligatorio. TypeScript infiere los tipos a partir de los valores pasados, si es posible. Pero a veces es conveniente especificarlo explícitamente, por ejemplo, si el tipo no se puede inferir o hay varias opciones.
function identity<T>(value: T): T { return value; } identity(5); // T = number (auto) identity<string>('s'); // T = string (explícito)
Historia
En un proyecto de e-commerce, se escribió un repositorio genérico para diferentes entidades, pero se olvidaron de la restricción de tipo. Como resultado, cualquier objeto podía ser pasado al genérico, y una vez se guardó una entidad con campos incompatibles. Los tipos no protegieron contra el error.
Historia
Se pasó una matriz a una función plantilla, esperando obtener una matriz con un tipo de elementos. Pero la función devolvió any[], ya que el genérico no fue especificado explícitamente y TypeScript no pudo inferir el tipo. El error solo se notó en producción.
Historia
Un desarrollador principiante creó una clase genérica sin restricción de tipo, utilizó un campo que no existía en todos los tipos. El compilador no dio errores, pero al acceder a una propiedad inexistente, toda la funcionalidad se rompía.