Los genéricos en TypeScript nos permiten definir funciones, clases o componentes que admiten un tipo como parte de su definición.
De esta forma, pueden comportarse diferente de forma diferente, en función del tipo recibido, adaptando su comportamiento genérico a los diferentes tipos.
Definición de funciones genéricas
Los genéricos se definen utilizando el símbolo < >
, y se pueden aplicar tanto a variables como a funciones.
Por ejemplo, podemos crear una función genérica que acepte cualquier tipo de dato:
function imprimirValor<T>(valor: T): void {
console.log(valor);
}
En este ejemplo,
<T>
es el tipo genérico que se puede utilizar para representar cualquier tipo de dato.- La función
imprimirValor
acepta un parámetrovalor
de tipoT
y simplemente lo imprime en la consola.
Es muy habitual usar “T” (de “Type”) para denominar al tipo que recibe la función. Pero es posible usar cualquier otra letra o nombre.
Creación de una clase genérica
Además de las funciones, también podemos crear clases genéricas en TypeScript. Esto nos permite crear clases que pueden trabajar con diferentes tipos de datos.
class Coleccion<T> {
private elementos: T[] = [];
agregar(elemento: T): void {
this.elementos.push(elemento);
}
obtener(indice: number): T {
return this.elementos[indice];
}
}
En este ejemplo,
- Hemos creado una clase genérica llamada
Coleccion
que puede almacenar cualquier tipo de dato. - La clase tiene un método
agregar
que acepta un elemento de tipoT
y lo añade a una lista interna. - También tiene un método
obtener
que devuelve el elemento en un índice específico.
Restricciones de tipo en genéricos
En ocasiones, es posible que queramos restringir los tipos que se pueden utilizar** con un genérico (por ejemplo, si queremos asegurarnos de que solo se puedan utilizar tipos numéricos con una función genérica)
Podemos lograr esto utilizando restricciones de tipo en los genéricos. Por ejemplo:
function sumarNumeros<T extends number>(a: T, b: T): number {
return a + b;
}
En este ejemplo,
- Hemos utilizado la palabra clave
extends
para indicar que el tipo genéricoT
debe ser un subtipo denumber
. - Esto nos permite utilizar la función
sumarNumeros
con cualquier tipo numérico, pero no con otros tipos de datos.
Inferencia de tipos en genéricos
TypeScript tiene la capacidad de inferir automáticamente el tipo genérico en función del tipo de datos proporcionado *(es deicr, que no tenemos que ponerlo nosotros “a mano”)
Esto nos permite escribir código más limpio y conciso sin tener que especificar explícitamente el tipo genérico en cada llamada. Por ejemplo, consideremos la siguiente función genérica:
function imprimirValor<T>(valor: T): void {
console.log(valor);
}
Si llamamos a esta función sin especificar el tipo genérico:
imprimirValor(42);
TypeScript inferirá automáticamente que el tipo genérico es number
, ya que hemos pasado un número como argumento.