TypeScript Generics se utiliza para generar código reutilizable y seguro desde el punto de vista de los tipos. Puedes aplicar TypeScript Generics a funciones, clases, interfaces y tipos, entre otros.

¿Qué son los TypeScript Generics?

En casi todos los lenguajes de programación existen herramientas que permiten a los usuarios crear plantillas de código y reutilizarlas más adelante o en otros proyectos. El objetivo no solo es ahorrar tiempo, sino también crear un código seguro que se pueda integrar perfectamente en nuevos entornos. De esta forma, puedes escribir y replicar diferentes componentes, funciones y estructuras de datos completas sin perder la integridad del tipo de dato. En TypeScript, estas tareas se llevan a cabo con Generics. Los tipos de datos se pueden pasar como parámetros a otros tipos, funciones u otras estructuras de datos.

Sintaxis y funcionamiento con un ejemplo sencillo

La base para trabajar con TypeScript Generics son las variables genéricas. Funcionan como marcadores de posición que representan el tipo de dato que se especificará más adelante. En el código, se identifican con cualquier letra mayúscula. Al crear el código, se introducen las variables entre paréntesis angulares y se les asigna el tipo real, de modo que el marcador de posición se reemplaza por la función TypeScript, interfaz o clase TypeScript deseada. A dicho marcador de posición también se le conoce como parámetro de tipo. También puedes colocar varios parámetros de tipo dentro de un mismo paréntesis. A continuación, te mostramos un ejemplo sencillo para que reconozcas la sintaxis de TypeScript Generics:

function FuncionEjemplo<T>(parametro1: T): void {
    console.log(`El tipo de dato del parámetro ${parametro1} es: ${typeof parametro1}`)
}
typescript

Aquí utilizamos el nombre de la función (“FuncionEjemplo”) para definir la variable genérica “T”. En el siguiente código, declaramos la variable como un string, una cadena de caracteres:

FuncionEjemplo<string>("Esto es un string.");
typescript

Al pasar el valor del parámetro string a la función, obtenemos el siguiente resultado:

El tipo de dato del parámetro Esto es un string. es: string
typescript

TypeScript Generics con dos variables

TypeScript Generics funciona de forma muy similar cuando se utilizan dos o más variables genéricas como marcadores de posición. En el siguiente ejemplo, almacenamos las variables “T” y “U” como tipos para los parámetros “parametro1” y “parametro2”. Separa las variables con una coma:

function FuncionEjemplo<T, U>(parametro1: T, parametro2: U): string {
    return JSON.stringify({parametro1, parametro2});
}
typescript

Ahora asignamos tipos de datos y valores a los dos marcadores de posición. En este caso, los tipos de datos son number y string, y los valores son “11” y “Jugador”. Aquí tienes el código correspondiente:

const str = FuncionEjemplo<number, string>(11, "Jugador");
console.log(str);
typescript

Ejemplos de clases reutilizables

Si quieres utilizar TypeScript Generics para crear clases reutilizables, también es posible. En el siguiente ejemplo, utilizamos generics para obtener un número como resultado. Aquí tienes el código correspondiente:

class ValorNumerico<T> {
    private _value: T | undefined;
    constructor(private name: string) {}
    public setValue(value: T) {
        this._value = value;
    }
    public getValue(): T | undefined {
        return this._value;
    }
    public toString(): string {
        return `${this.name}: ${this._value}`;
    }
}
let value = new ValorNumerico<number>('miNumero');
value.setValue(11);
console.log(value.toString());
typescript

El resultado es el siguiente:

miNumero: 11
typescript

Este principio también funciona con otros tipos de datos y con varias variables genéricas. Puedes verlo en el siguiente ejemplo:

class ClaseEjemplo<T, U> {
nombre: T;
apellido: U;
constructor(nombre: T, apellido: U) {
	this.nombre = nombre;
	this.apellido = apellido;
	}
}
typescript

Ahora asignamos el tipo de datos string a las variables y les damos los valores deseados:

const persona1 = new ClaseEjemplo<string, string>("Julia", "Pérez");
console.log(`${persona1.nombre} ${persona1.apellido}`)
typescript

El resultado es el siguiente:

Julia Pérez
typescript

Si quieres combinar diferentes tipos de datos, sigue el siguiente ejemplo:

class ClaseEjemplo<T, U> {
numero: T;
palabra: U;
constructor(numero: T, palabra: U) {
	this.numero = numero;
	this.palabra = palabra;
	}
}
typescript

A los marcadores de posición se les asignan ahora los tipos de datos number y string, así como sus valores:

const combinacion = new ClaseEjemplo<number, string>(11, "Jugador");
console.log(`${combinacion.numero} ${combinacion.palabra}`);
typescript

El resultado es el siguiente:

11 Jugador
typescript

Uso con interfaces

También puedes usar TypeScript Generics con interfaces, y se recomienda hacerlo. El procedimiento es similar al de declarar una clase:

interface Interfaz<T> {
	valor: T;
}
typescript

Ahora implementamos la interfaz en la clase “ClaseEjemplo”. Asignamos a la variable “T” el tipo de dato string:

class ClaseEjemplo implements Interfaz<string> {
	valor: string = "Esto es un ejemplo con una interfaz";
}
const salida = new ClaseEjemplo();
console.log(salida.valor)
typescript

El resultado es el siguiente:

Esto es un ejemplo con una interfaz
typescript

Crear arrays genéricos

También puedes utilizar TypeScript Generics para crear arrays de TypeScript. Aquí tienes un ejemplo de código sencillo, en el que usamos la función reverse para invertir el orden de los números en un array:

function reverse<T>(array: T[]): T[] {
    return array.reverse();
}
let numeros: number[] = [10, 7, 6, 13, 9];
let nuevoOrden: number[] = reverse(numeros);
console.log(nuevoOrden);
typescript

El resultado es el siguiente:

[9, 13, 6, 7, 10]
typescript

TypeScript Generics para tipos condicionales

Para finalizar, te mostramos cómo usar TypeScript Generics con tipos condicionales. El resultado cambia dependiendo de si se cumple o no una condición. En el siguiente ejemplo, la condición que debe cumplirse es que el tipo de dato sea string. Aquí tienes el código:

type EsEstoUnString<T> = T extends string ? true : false;
type A = "ejemplo";
type B = {
	nombre: string;
};
type PrimerResultado = EsEstoUnString<A>;
type SegundoResultado = EsEstoUnString<B>;
typescript

type A es el string “ejemplo”, mientras que type B es un objeto con la propiedad “nombre” y el tipo de dato string. A continuación, almacenamos ambos tipos como “PrimerResultado” y “SegundoResultado”. Al revisar ambos tipos, veremos que “PrimerResultado” es true porque es un string, mientras que “SegundoResultado” sigue siendo false.

Consejo

Despliega tu página web o aplicación directamente desde GitHub: Deploy Now de IONOS es la mejor opción para páginas web y aplicaciones, gracias a su detección automática de frameworks, su rápida configuración y su óptima escalabilidad. ¡Elige la tarifa que mejor se adapta a tu proyecto!

¿Le ha resultado útil este artículo?
Ir al menú principal