Saltar al contenido

TypeScript 5.x: características que cambian cómo escribes código

Andrés Ujpán
Fecha de publicación:
2 min de lectura

TypeScript continúa evolucionando a un ritmo rápido. Las versiones 5.x trajeron cambios que van más allá de las mejoras de rendimiento: rediseñan patrones que hemos estado usando durante años.

Tabla de contenido

Decoradores estándar (TC39 Stage 3)

Finalmente. Después de años con la versión experimental, TypeScript 5.0 adoptó los decoradores estándar de TC39. La sintaxis es similar pero la semántica cambió bastante.

// Class decorator — before (experimental)
@sealed
class OldClass { ... }

// Standard decorator — TS 5.x
function logged<T extends new (...args: unknown[]) => unknown>(
  target: T,
  _ctx: ClassDecoratorContext,
) {
  return class extends target {
    constructor(...args: unknown[]) {
      super(...args);
      console.log(`[LOG] Instance of ${target.name} created`);
    }
  };
}

@logged
class UserService {
  constructor(private db: Database) {}
}decorators.ts

Decoradores de método y de accesores (accessor)

function measure(_target: unknown, ctx: ClassMethodDecoratorContext) {
  const name = String(ctx.name);
  return function (this: unknown, ...args: unknown[]) {
    const start = performance.now();
    const result = (this as Record<string, Function>)[name](...args); 
    const result = Reflect.apply(
      _target as Function,
      this,
      args 
    ); 
    console.log(`${name} took ${performance.now() - start}ms`);
    return result;
  };
}

class ReportService {
  @measure
  async generatePDF(id: string) {
    /* ... */
  }
}method-decorator.ts

Parámetros de tipo const (const Type Parameters)

Antes necesitabas as const en cada llamada para inferir tuplas literales. Ahora puedes declararlo en el genérico:

// Before: inferred as string[]
function head<T>(arr: T[]) {
  return arr[0];
}
head(["a", "b"]); // type: string

// Now: inferred as the exact literal
function head<const T extends readonly unknown[]>(arr: T) {
  return arr[0];
}
head(["a", "b"] as const); // type: "a"
head(["a", "b"]); // type: "a"  ← works without as constconst-type-params.ts

Operador satisfies (consolidado)

Introducido en la versión 4.9 pero ya es parte del flujo de trabajo diario. Permite validar que un valor cumple con un tipo sin hacerlo más general (“widening”):

type Palette = {
  red: [number, number, number] | string;
  green: [number, number, number] | string;
  blue: [number, number, number] | string;
};

const palette = {
  red: [255, 0, 0],
  green: "#00ff00",
  blue: [0, 0, 255],
} satisfies Palette; 

// Now TypeScript knows that red is a tuple, not string
palette.red.at(0); // ✓ — before it threw an errorsatisfies.ts

Mejoras en la inferencia de infer

// Extract the return type filtered by constraint
type ReturnIfString<T> = T extends () => infer R extends string
  ? R
  : never;

type A = ReturnIfString<() => "hello">; // "hello"
type B = ReturnIfString<() => number>;  // neverinfer-extends.ts

Rendimiento: modo --incremental y --composite

TS 5.x optimizó las compilaciones incrementales. En proyectos grandes, la mejora puede ser de hasta 3 veces:

{
  "compilerOptions": {
    "composite": true,
    "incremental": true,
    "tsBuildInfoFile": ".tsbuildinfo",
    "moduleResolution": "bundler"
  }
}tsconfig.json

Consejo: combina composite con referencias de proyecto (references) para monorepos. Cada paquete compilará solo lo que haya cambiado.

Resumen rápido

CaracterísticaVersiónImpacto
Decoradores estándar5.0Alto — reemplaza a experimental
Parámetros de tipo const5.0Medio — menos as const
satisfies4.9 / consolidado en 5.xAlto — tipado más expresivo
infer ... extends5.xMedio — tipos condicionales más precisos
Compilación incremental mejorada5.xAlto en monorepos
Artículo Anterior
Agentes de IA autónomos: la nueva forma de construir software en 2026
Fecha de publicación:
3 min de lectura
Lectura Recomendada
Rust para desarrolladores de JavaScript: el salto que vale la pena dar
Fecha de publicación:
2 min de lectura
100%