Translate

sábado, 28 de septiembre de 2024

Clases Genéricas en TypeScript


Las clases genéricas en TypeScript nos permiten escribir código flexible y reutilizable. En lugar de definir clases específicas para cada tipo de dato, podemos crear clases genéricas que trabajen con múltiples tipos, manteniendo la seguridad de tipos que ofrece TypeScript.

Una clase genérica es aquella que acepta uno o más parámetros de tipo. Estos parámetros de tipo funcionan como marcadores de posición que representan un tipo de dato específico en el momento de la instanciación de la clase.

Veamos un ejemplo: 


class Caja<T> {

    contenido: T;


    constructor(contenido: T) {

        this.contenido = contenido;

    }


    obtenerContenido(): T {

        return this.contenido;

    }

}



En este ejemplo, T es un parámetro de tipo que se utiliza en la clase Caja. No sabemos qué tipo de dato es T hasta que se instancie la clase con un tipo específico.

Puedes instanciar la clase `Caja` con cualquier tipo de dato:


const cajaDeNumero = new Caja<number>(123);

console.log(cajaDeNumero.obtenerContenido()); // 123

const cajaDeTexto = new Caja<string>('Hola');

console.log(cajaDeTexto.obtenerContenido()); // Hola


El tipo `T` se reemplaza con el tipo proporcionado (`number` o `string`), manteniendo el control de tipos y evitando errores durante la compilación.

También es posible utilizar múltiples parámetros de tipo en una clase genérica. Por ejemplo:


class Par<K, V> {

    clave: K;

    valor: V;


    constructor(clave: K, valor: V) {

        this.clave = clave;

        this.valor = valor;

    }


    obtenerClave(): K {

        return this.clave;

    }


    obtenerValor(): V {

        return this.valor;

    }

}


const par = new Par<string, number>('edad', 30);

console.log(par.obtenerClave()); // 'edad'

console.log(par.obtenerValor()); // 30


En este caso, `Par` es una clase genérica que acepta dos parámetros de tipo: `K` para la clave y `V` para el valor. Luego, se instanció con `string` como clave y `number` como valor.

A veces queremos limitar los tipos que un parámetro genérico puede aceptar. Esto se hace usando la palabra clave `extends` para aplicar una restricción al parámetro de tipo.


class LimitarCaja<T extends number | string> {

    contenido: T;


    constructor(contenido: T) {

        this.contenido = contenido;

    }


    mostrarContenido(): void {

        console.log(`Contenido: ${this.contenido}`);

    }

}


const cajaTexto = new LimitarCaja('Hola');

cajaTexto.mostrarContenido(); // Contenido: Hola


const cajaNumero = new LimitarCaja(123);

cajaNumero.mostrarContenido(); // Contenido: 123


Aquí, la clase LimitarCaja solo acepta tipos que sean number o string, lo que añade una restricción al tipo T.

Como ventaja de las clases genericas podemos nombrar: 

  • Reutilización del código: Puedes usar la misma clase para diferentes tipos sin necesidad de duplicar código.
  • Seguridad de tipos: TypeScript asegura que se utilicen los tipos correctos, evitando errores en tiempo de ejecución.
  • Flexibilidad: Permiten que el código sea más flexible, ya que puedes trabajar con cualquier tipo sin perder el control del sistema de tipos.

Las clases genéricas en TypeScript son una herramienta poderosa para crear código flexible y reutilizable. Al permitir que las clases trabajen con múltiples tipos, puedes crear soluciones que se adapten a diferentes escenarios sin sacrificar la seguridad de tipos que hace que TypeScript sea tan útil.