Introducción: Por qué «simplemente compila» es un mal criterio
\nImagine la situación: abre un Pull Request en GitHub, ve la marca verde de CI y escucha una voz interior: «Los tipos coinciden, entonces el código es correcto». ¿Le suena familiar? Si es así, está cayendo en la trampa que llamamos «falsa sensación de seguridad de TypeScript».
\nTypeScript no es una panacea. No detecta errores lógicos, no verifica requisitos de negocio y ciertamente no garantiza que su código no falle en tiempo de ejecución. Por eso, el code review en TypeScript no se trata de «echar un vistazo rápido», sino de un enfoque sistemático. En este artículo, contaré en qué realmente vale la pena fijarse cuando revisa código TypeScript. Escribo un blog en PythonLib, y aquí estamos acostumbrados a profundizar — prepárese.
\n\n1. Tipo any: una bandera roja
\nLo más obvio, pero por alguna razón lo más frecuente. any es el interruptor de TypeScript. Si ve any en el código, su tarea es entender: ¿es pereza del autor o un caso realmente justificado?
Ejemplo malo:
\nfunction processData(data: any) {\n return data.name.toLowerCase();\n}\nAquí perdemos toda la información sobre el tipo. Si data llega como null o undefined — hola, error en tiempo de ejecución.
Ejemplo bueno:
\ninterface UserData {\n name: string;\n age?: number;\n}\n\nfunction processData(data: UserData) {\n return data.name.toLowerCase();\n}\nQué revisar en el code review: Si any se usa de todos modos (por ejemplo, para trabajar con JSON de estructura desconocida), ¿requiere el autor una validación de entrada? A menudo, any oculta la falta de tipado adecuado para datos externos.
2. Strict mode: no lo desactive
\nLo primero que reviso en tsconfig.json es la bandera strict: true. Si no está, se está privando de toda una capa de verificaciones: strictNullChecks, noImplicitAny, strictFunctionTypes y otras.
Sin strictNullChecks puede escribir:
const user = getUser(); // puede devolver null\nconst name = user.name; // TS no se quejará, pero en tiempo de ejecución fallará\nEn el code review: Si ve que el proyecto funciona sin strict mode — dé la alarma. Es deuda técnica que se acumula exponencialmente. Es mejor dedicar un día a activar el strict mode y corregir errores, que un mes a cazar bugs en producción.
\n\n3. Genéricos: poder y responsabilidad
\nLos genéricos son el superpoder de TypeScript. Pero un gran poder conlleva una gran responsabilidad. En el code review siempre miro: ¿el autor complicó demasiado los tipos?
\nEjemplo de complejidad excesiva:
\nfunction identity<T extends Record<string, unknown>>(arg: T): T {\n return arg;\n}\n¿Por qué limitar T a Record<string, unknown> si simplemente devolvemos lo mismo? Es suficiente:
function identity<T>(arg: T): T {\n return arg;\n}\nQué revisar:
\n- \n
- ¿Se usan genéricos donde se necesita flexibilidad, o se puede usar un tipo concreto? \n
- ¿Hay restricciones (extends) redundantes que dificultan la reutilización? \n
- ¿Se infieren los tipos correctamente — no tiene el usuario que especificar manualmente
<SomeType>donde TS podría deducirlo por sí mismo? \n
4. unknown vs any: elija el arma correcta
\nCuando trabaja con datos cuyo tipo desconoce (API, localStorage, entrada de usuario), use unknown, no any. unknown le obliga a verificar explícitamente el tipo antes de usarlo.
Malo:
\n<