TypeScript avanzado: cómo usar tipos para escribir mejor código (no solo más complejo)
Hay un punto en TypeScript donde todo deja de ser básico… y empieza a volverse innecesariamente complicado. Union types, generics, mapped types, decorators… Los aprendes, los usas, pero muchas veces no mejoran realmente tu código. Y ese es el problema: saber TypeScript avanzado no significa usarlo bien.
El error más común: usar TypeScript para impresionar, no para resolver
He visto código con tipos complejos que nadie entiende. Y eso no es mejor código. Es código más difícil de mantener. TypeScript debería ayudarte a:
prevenir errores
hacer el código más claro
mejorar la experiencia del developer
Union types: simples pero poderosos
Esto parece básico, pero bien usado cambia mucho.
type Status = 'pending' | 'approved' | 'rejected';
function handle(status: Status) {
if (status === 'approved') {
return 'ok';
}
}
Evitas errores sin complicar nada.
El verdadero poder: discriminated unions
Aquí ya empiezas a escribir código más sólido.
type Result =
| { type: 'success'; data: string }
| { type: 'error'; message: string };
function handle(result: Result) {
if (result.type === 'success') {
return result.data;
}
return result.message;
}
TypeScript ya sabe qué propiedades existen. No necesitas validar manualmente todo.
Genéricos: donde muchos se complican de más
Los genéricos son potentes… pero fáciles de abusar. Ejemplo correcto:
function identity<T>(value: T): T {
return value;
}
Ejemplo innecesariamente complejo:
type Crazy<T, K extends keyof T> = T[K] extends infer U ? U : never;
Si tienes que pensar demasiado para entenderlo, probablemente está mal.
Mapped types: útiles en casos reales
Aquí sí hay valor real.
type User = {
id: number;
name: string;
};
type ReadonlyUser = {
readonly [K in keyof User]: User[K];
};
Esto evita modificaciones accidentales.
Utility types: usa lo que ya existe
Muchos desarrolladores reinventan lo que TypeScript ya tiene.
type User = {
id: number;
name: string;
email: string;
};
type UserPreview = Pick<User, 'id' | 'name'>;
type UserUpdate = Partial<User>;
Menos código, más claridad.
Decoradores: poderosos, pero con cuidado
Útiles en frameworks como NestJS. Pero en proyectos simples… pueden ser overkill.
function log(target: any, key: string) {
console.log(key);
}
No todo necesita metaprogramación.
El verdadero objetivo de TypeScript avanzado
No es escribir tipos complejos. Es escribir código más claro, más seguro y más mantenible. Si tu código es más difícil de entender después de usar TypeScript… lo estás usando mal.
Conclusión
TypeScript avanzado no se trata de saber más sintaxis. Se trata de:
usar lo necesario
evitar complejidad innecesaria
pensar en quien va a leer tu código
El mejor código no es el más complejo. Es el que cualquiera puede entender rápido. Si estás trabajando con TypeScript y quieres mejorar la arquitectura de tu código o escalar proyectos correctamente, puedo ayudarte a estructurarlos mejor.
Escríbeme y vemos tu caso.


