Skip to main content

Programación genérica en TypeScript

⏱ Dedicación recomendada: 0 minutos
Esto considera el contenido visible y relevante, e ignora texto colapsado o marcado como opcional.


r8vnhill/

Al igual que en Kotlin, TypeScript también soporta el polimorfismo paramétrico utilizando tipos genéricos. Esto permite definir funciones, clases e interfaces que pueden trabajar con cualquier tipo de dato sin especificarlo de antemano.

Función Genérica en TypeScript

En TypeScript, la función de identidad se implementa con tipos genéricos de la siguiente manera:

test('when called with a string, then returns the string', () => {
const value = 'hello';
expect(identity(value)).toBe(value);
});

test('when called with a number, then returns the number', () => {
const value = 42;
expect(identity(value)).toBe(value);
});
src/generics/identity.ts
export function identity<T>(value: T): T {
return value;
}

Clases Genéricas en TypeScript

TypeScript también soporta clases genéricas. Un ejemplo típico es la clase Box que puede almacenar un valor de cualquier tipo T:

test('when containing a string, then returns the string', () => {
const box: Box<string> = { value: 'hello' };
expect(box.value).toBe('hello');
});

test('when containing a number, then returns the number', () => {
const box: Box<number> = { value: 42 };
expect(box.value).toBe(42);
});
src/generics/box.ts
export class Box<T> {
constructor(public value: T) {}
}

Interfaces Genéricas en TypeScript

Similar a Kotlin, TypeScript también permite definir interfaces genéricas. Aquí está un ejemplo de una interfaz Repository genérica para cualquier tipo T:

test('when saving a user, then can find the user by id', () => {
const repository = new UserRepository();
const user: User = { id: 1, name: 'Jeon Geuk-jin' };
expect(repository.findById(user.id)).toBeUndefined();
repository.save(user);
expect(repository.findById(user.id)).toEqual(user);
});
export interface Repository<T> {
save(value: T): void;
findById(id: number): T | undefined;
}

export class UserRepository implements Repository<User> {}

Comparación Final

CaracterísticaKotlinTypeScript
Función Genéricafun <T> identity(value: T): Tfunction identity<T>(value: T): T
Clases Genéricasclass Box<T>(val value: T)class Box<T> { constructor(public value: T) }
Interfaces Genéricasinterface Repository<T> { ... }interface Repository<T> { ... }
Tipo de Parámetro InferidoInferencia fuerteInferencia flexible
Sistema de TiposEstático y seguro en tiempo de compilaciónEstático, pero más flexible

Beneficios y limitaciones

Beneficios

  • Flexibilidad: TypeScript permite mayor flexibilidad en la inferencia de tipos, lo que puede hacer que sea más fácil de usar en proyectos donde el tipado rígido no es siempre necesario.
  • Integración con JavaScript: Al ser un superconjunto de JavaScript, TypeScript facilita la adopción gradual de tipos en proyectos JavaScript existentes, lo que lo convierte en una excelente opción para proyectos que evolucionan.
  • Desarrollo web: TypeScript es ampliamente utilizado en el desarrollo de aplicaciones web modernas, particularmente en frameworks como Angular, lo que lo hace relevante para desarrolladores web.

Limitaciones

  • Tipado menos estricto: Aunque TypeScript tiene un sistema de tipos estáticos, es más flexible que el de Kotlin, lo que puede llevar a errores difíciles de detectar en aplicaciones grandes si no se aplica correctamente.
  • Menor seguridad de tipos: Debido a que TypeScript permite el tipado opcional y es más permisivo, no siempre se garantiza la misma seguridad en tiempo de compilación que en Kotlin.
  • Complejidad añadida: En proyectos grandes, la configuración y gestión de tipos en TypeScript puede volverse compleja, especialmente cuando se integran librerías de JavaScript que no tienen tipos definidos.

¿Qué Aprendimos?

En esta lección, hemos explorado cómo TypeScript soporta el polimorfismo paramétrico de manera similar a Kotlin a través del uso de tipos genéricos. Ambos lenguajes permiten escribir código más flexible y reutilizable al permitir que funciones, clases e interfaces trabajen con cualquier tipo de dato. Sin embargo, también hemos visto algunas diferencias clave en sus enfoques, como la flexibilidad del sistema de tipos de TypeScript frente a la mayor rigidez y seguridad del sistema de tipos de Kotlin.

Puntos clave

  • TypeScript ofrece un sistema de tipos más flexible, adecuado para proyectos que requieren integrarse con código JavaScript existente o aplicaciones web modernas.
  • Kotlin, por otro lado, proporciona un sistema de tipos más estricto y seguro, lo que garantiza una mayor seguridad en tiempo de compilación, evitando errores de tipo comunes.
  • Ambos lenguajes permiten la reutilización y generalización de código a través de funciones genéricas, clases genéricas, e interfaces genéricas, promoviendo buenas prácticas de programación como la abstracción y la seguridad de tipos.

Con esto, puedes aplicar el polimorfismo paramétrico en ambos lenguajes para escribir código más flexible y robusto, adaptado a diferentes tipos de datos sin comprometer la seguridad del código.

Bibliografías Recomendadas

  • 📚 "Generics". (2023). Baumgartner, S., en Typescript Cookbook: Real world type-level programming, (pp. 109–142.) O'Reilly.