Mascota Jacar — leyendo contigo Un portátil cuyos ojos siguen el cursor mientras lees.
Desarrollo de Software

TypeScript 5.4: tipos más potentes, menos trucos

TypeScript 5.4: tipos más potentes, menos trucos

Actualizado: 2026-05-03

TypeScript 5.4 se publicó el 6 de marzo de 2024 y encaja en esa categoría de releases que se describen como “incrementales” pero cuyo impacto real en el día a día es desproporcionado. No introduce un cambio de paradigma comparable a satisfies o a los template literal types, pero retira tres o cuatro fricciones que llevaban años presentes en cualquier base de código TypeScript medianamente genérica.

Puntos clave

  • NoInfer<T> elimina el patrón de dos type parameters que se usaba para acotar inferencia en funciones genéricas.
  • El narrowing dentro de callbacks síncronos (forEach, map) ya no requiere variables intermedias defensivas.
  • Object.groupBy y Map.groupBy quedan tipados, cerrando la última excusa para importar lodash solo por agrupar listas.
  • Las mejoras de rendimiento del compilador se notan en monorepos grandes, no en proyectos pequeños.
  • La migración desde 5.3 es npm install -D typescript@5.4 en la abrumadora mayoría de proyectos.

NoInfer: el arreglo que llevábamos años pidiendo

La estrella de la release es el utility type NoInfer<T>. Resuelve un problema específico pero omnipresente: cuando una función genérica toma varios parámetros que mencionan el mismo type parameter, TypeScript intenta inferirlo desde todos ellos, ensanchando el tipo resultante más allá de lo que el autor pretendía.

El caso canónico es una función que recibe una lista de valores permitidos y un valor por defecto. Si el segundo parámetro participa en la inferencia, puedes pasar un literal que no pertenece al conjunto y TypeScript lo aceptará, porque el propio acto de pasarlo ensancha C hasta incluirlo. Antes de 5.4 la solución pasaba por dos type parameters separados o un conditional type oscuro; ahora es una anotación trivial:

typescript
function createStreetLight<C extends string>(
  colors: C[],
  defaultColor?: NoInfer<C>
) {}

createStreetLight(["red", "yellow", "green"], "blue");
// Error: '"blue"' no es asignable a '"red" | "yellow" | "green"'

function withDefault<T>(value: T, fallback: NoInfer<T>): T {
  return value ?? fallback;
}
withDefault(42, 0);      // T = number, ok
withDefault("hi", 42);   // Error — T fijado a string

Los autores de Zod, tRPC y React Query lo incorporan en sus próximas versiones mayores, así que llegará a cualquier proyecto moderno aunque no lo uses explícitamente.

Narrowing preservado en closures síncronas

El segundo cambio que notarás esta semana es el narrowing preservado dentro de callbacks ejecutados síncronamente. Históricamente, un arr.every(x => typeof x === 'string') estrechaba el tipo de arr fuera del if, pero en cuanto entrabas en un forEach o map TypeScript olvidaba ese narrowing porque el callback podría, en teoría, ser llamado más tarde.

El compilador ahora reconoce que los métodos estándar de arrays son síncronos y mantiene el estrechamiento dentro del callback. El resultado práctico es:

  • Menos as string[] salpicados por el código.
  • Menos if (typeof x === 'string') defensivos redundantes.
  • Menos variables intermedias creadas solo para capturar el tipo estrechado.

Encaja bien con bases de código que ya usan patrones funcionales sobre arrays en TypeScript y con proyectos que aprovechan Deno Deploy para edge computing, donde TypeScript nativo es el runtime.

Object.groupBy y Map.groupBy

TS 5.4 tipa los métodos Object.groupBy y Map.groupBy que en ese momento estaban en stage 3 de TC39. La firma devuelve Partial<Record<K, T[]>>, con el Partial marcando correctamente que no todas las claves del union aparecen necesariamente.

Es una conveniencia directa que elimina una dependencia de lodash en proyectos que solo la usaban para esto.

Rendimiento del compilador

Las notas de release mencionan menor consumo de memoria, builds incrementales más rápidos y mejor deduplicación de type instances. En un proyecto de diez archivos no notarás nada. En un monorepo con cientos de paquetes y un tsc --build que tardaba minutos, la diferencia es perceptible —no transformadora, pero suficiente para que el CI respire.

Lo que no trae y lo que puede romper

Los breaking changes son menores y puntuales:

  • Homomorfismo más estricto en mapped type variations puede afectar a librerías con type gymnastics agresivo.
  • Algunas firmas de Function.prototype.bind se endurecen.

En código de aplicación la probabilidad de notarlo es prácticamente cero. Las ausencias de siempre (decorators estables completos, pipeline operator, pattern matching) siguen esperando movimientos en TC39.

Actualizar desde 5.3

En la abrumadora mayoría de proyectos la migración se reduce a tres pasos:

  1. npm install -D typescript@5.4
  2. Correr tsc --noEmit y comprobar si aparecen errores nuevos.
  3. Si usas @typescript-eslint, actualizar el parser a versión compatible en el mismo commit.

Vite, esbuild, swc, Next, Nuxt, SvelteKit y el resto del stack moderno no requieren cambios. Es una de las releases menos traumáticas de los últimos años. El proyecto está bien posicionado para aprovechar luego mejoras de ONNX Runtime en edge, donde TypeScript estricto en los tipos de tensores evita errores en producción.

Conclusión

TypeScript 5.4 no cambia cómo piensas sobre tipos, pero retira tres workarounds que llevabas años escribiendo sin darte cuenta. NoInfer convierte en una anotación trivial lo que antes requería dos type parameters o un conditional type oscuro. El narrowing preservado en closures elimina una categoría entera de casts molestos. Object.groupBy cierra la última excusa para importar lodash solo por agrupar una lista. Para un equipo activo, migrar pronto compensa: los patrones nuevos hacen el código más expresivo y los antiguos empiezan a oler a legacy más rápido de lo esperado.

¿Te ha resultado útil?
[Total: 10 · Media: 4.8]

Escrito por

CEO - Jacar Systems

Apasionado de la tecnología, la infraestructura cloud y la inteligencia artificial. Escribe sobre DevOps, IA, plataformas y software desde Madrid.