Noticias

TypeScript 7.1 beta: el compilador en Go estrena API, compila más rápido y gasta hasta la mitad de memoria

6 min de lectura

Microsoft ha publicado la beta de TypeScript 7.1, la primera versión con novedades de peso desde que el compilador se reescribió en Go. Trae lo que más se echaba en falta en la 7.0: una API para crear herramientas sobre el compilador nuevo. Además, añade un sistema de complementos para que Vue, Svelte o Astro se revisen igual que un archivo .ts, reconoce ECMAScript 2026 y compila hasta 1.9 veces más rápido que la 7.0 en proyectos grandes. Se instala con npm install -D typescript@beta.

TypeScript 7.0, publicada en julio, cambió el compilador escrito en TypeScript por uno escrito en Go, unas diez veces más rápido según Microsoft. El precio fue dejar fuera la API de JavaScript que usaban linters, empaquetadores y extensiones de editor para preguntarle cosas al compilador: quien la necesitaba tenía que seguir con TypeScript 6. Por eso el editor en el navegador de nuestro curso de TypeScript usa todavía la 6.0.3.

Hemos instalado la beta en un contenedor con Node 24: npm ya la ofrece con la etiqueta beta (versión 7.1.0-beta), mientras que latest sigue siendo la 7.0.2. Los mensajes de error de esta noticia salen de ejecutar tsc --locale es con esa versión.

Claves de TypeScript 7.1

  • Vuelve la API, con otra forma: ya no es un único módulo, sino varios puntos de entrada: typescript/sync (un cliente síncrono con el programa y el revisor de tipos), typescript/async (lo mismo con promesas), typescript/fs (sistemas de archivos virtuales) y typescript/ast (el árbol de sintaxis, sus comprobaciones y su fábrica de nodos).
  • Hay que liberar los objetos: la API habla con el compilador en Go, así que el recolector de basura de JavaScript no basta. Cada objeto se cierra a mano o se declara con using, la palabra nueva de JavaScript que lo libera al salir del bloque.
  • Instantáneas: un snapshot guarda el estado de todos los proyectos en un momento dado; al cambiar un archivo se deriva uno nuevo sin reconstruirlo todo, y el anterior sigue disponible.
  • «Content mappers»: complementos que traducen un archivo .vue, .svelte o .astro a lo que TypeScript entiende y señalan qué trozo corresponde a qué línea del original. Es el modelo de Volar, que ahora el compilador adopta como propio. Ya hay prototipos para Astro, CSS Modules, Ember, MDX, Svelte y Vue.
  • Atributos de importación en los módulos ambientales: se puede declarar qué tipo devuelve un import … with { type: "text" } y TypeScript avisa si se olvida el atributo.
  • import source: soporte para esta propuesta de ECMAScript, que devuelve un módulo ya analizado pero sin ejecutar. Su uso práctico hoy es WebAssembly: el resultado se pasa tal cual a WebAssembly.instantiate.
  • ECMAScript 2026: --target es2026 y --lib es2026 pasan a ser estables, con Math.sumPrecise(), Error.isError(), getOrInsert() en Map, base64 y hexadecimal en Uint8Array o Array.fromAsync().
  • Más rápido y con menos memoria: más de cuarenta optimizaciones. En la documentación de MUI, la revisión pasa de 22.2 a 11.9 segundos y de 8,093 a 4,079 MiB.
  • Una regla de tipos más estricta: código que compilaba con la 7.0 puede dar un error nuevo, como se ve más abajo.

La API, probada

El ejemplo del anuncio crea un programa en un sistema de archivos que solo existe en memoria. Lo hemos reducido a lo mínimo: un archivo virtual que asigna un texto a una variable number, y la pregunta de cuántos errores tiene. Node 24 lo ejecuta directamente desde el .mts, sin compilar, porque borra los tipos al cargarlo:

import { API } from "typescript/sync";
import { createFileSystemWithLib } from "typescript/fs";
import { resolve } from "node:path";

const f = resolve("virtual.ts");
using api = new API();
using snap = api.createSnapshot({
  fileSystem: createFileSystemWithLib([[f, 'export const respuesta: number = "cuarenta y dos";']]),
  createPrograms: [{ rootFiles: [f], compilerOptions: { strict: true, noEmit: true } }],
});
using prog = snap.operation.createdPrograms[0];
console.log("errores:", prog.getSemanticDiagnostics().length);
node api.mts  (Node 24.22, typescript 7.1.0-beta)errores: 1

Por dentro, la API no ejecuta el compilador en JavaScript: arranca el binario nativo de Go que trae el paquete y se comunica con él por tuberías. Por eso es rápida y por eso hay que cerrar cada objeto. También explica que no sirva todavía en un navegador: el paquete no incluye una versión en WebAssembly.

Lo nuevo en el día a día

Los atributos de importación ya permitían cargar un texto, unos bytes o una hoja de estilos con with { type: … }, pero los tipos se declaraban por extensión (*.md, *.txt…), así que nada impedía olvidar el atributo. Ahora la declaración va por atributo:

// tipos.d.ts
declare module "*" with { type: "text" } {
    const content: string;
    export default content;
}

// main.ts
import leeme from "./LEEME.md" with { type: "text" };
import olvido from "./LEEME.md";
const mal: number = leeme;
npx tsc --noEmit --strict --module esnext --moduleResolution bundler --locale es tipos.d.ts main.tsmain.ts(2,20): error TS2307: No se encuentra el módulo "./LEEME.md" ni sus declaraciones de tipos correspondientes.
main.ts(3,7): error TS2322: El tipo 'string' no se puede asignar al tipo 'number'.

El primer error es el import sin atributo; el segundo demuestra que leeme ya llega como string. Microsoft aclara que estas declaraciones no vienen incluidas en TypeScript: cada proyecto las escribe según su entorno, y recomienda que las bibliotecas no las publiquen.

Con ECMAScript 2026 pasa algo parecido a cada año: lo que estaba en esnext se estabiliza. Un archivo que usa Math.sumPrecise, getOrInsert y Error.isError compila sin errores con --target es2026; con es2025, el compilador explica qué cambiar:

const total = Math.sumPrecise([0.1, 0.2, 0.3]);
const veces = new Map<string, number>();
veces.set("a", veces.getOrInsert("a", 0) + 1);
console.log(total, veces, Error.isError(new Error("x")));
npx tsc --noEmit --strict --target es2025 --locale es es2026.tses2026.ts(1,20): error TS2550: No existe la propiedad "sumPrecise" en el tipo "Math". ¿Necesita cambiar la biblioteca de destino? Pruebe a cambiar la opción del compilador "lib" a "es2026" o posterior.
es2026.ts(3,22): error TS2550: No existe la propiedad "getOrInsert" en el tipo "Map<string, number>". ¿Necesita cambiar la biblioteca de destino? Pruebe a cambiar la opción del compilador "lib" a "es2026" o posterior.
es2026.ts(4,33): error TS2550: No existe la propiedad "isError" en el tipo "ErrorConstructor". ¿Necesita cambiar la biblioteca de destino? Pruebe a cambiar la opción del compilador "lib" a "es2026" o posterior.

El cambio que puede romper algo afecta a los tipos condicionales que se distribuyen sobre una unión. Dentro de cada rama, el parámetro ya no se trata como el original, sino como un trozo de él, sin relación con otros tipos que dependían del original. Es el ejemplo del anuncio, que la 7.0 aceptaba:

type Show<A extends number, B extends A> = `${B} extends ${A}`;

type Issue<A extends number, B extends A> =
    A extends B ?
        never :
        Show<A, B>;
npx tsc --noEmit --strict --locale es distrib.tsdistrib.ts(6,17): error TS2344: El tipo 'B' no cumple la restricción 'A'.
  'B' solo se puede asignar al 'A' no distribuido, pero 'A' se ha distribuido aquí.

La 7.0 dejaba escribir Issue<0 | 1, 0> y producía el tipo "0 extends 1", que es falso. Microsoft lo explica con animales: un gato es un animal, pero no es cualquier animal.

Qué gana quien escribe herramientas (y qué falta)

Para quien solo usa tsc, la 7.1 es sobre todo velocidad y memoria: en las pruebas de Microsoft, con cuatro hilos de revisión, el ahorro de tiempo va del 13 % en Bluesky al 47 % en la documentación de MUI, y la memoria baja entre un 16 % y un 50 %. Para el ecosistema, lo importante es la API: sin ella, los linters, empaquetadores y extensiones que se apoyan en el compilador no podían usar el de Go. Ahora tienen una vía, aunque distinta de la de la versión 6, así que tendrán que adaptarse.

Los content mappers resuelven un problema viejo de Vue o Svelte: Volar daba buena ayuda en el editor, pero la revisión desde la línea de órdenes iba por otro camino. Con la 7.1, el mismo complemento sirve para los dos. Como son programas externos que el compilador ejecuta, hay que permitirlo: en la terminal, con tsc --runExternalCode; en VS Code, aceptando la confianza en el espacio de trabajo y los permisos del complemento.

En el editor de decodigo no cambia nada por ahora: necesita un compilador que funcione dentro del navegador, y la API de la 7.1 depende de un binario nativo. Lo que se aprende en el curso sirve igual con la 7.1: la regla nueva de tipos distribuidos es el único cambio de comportamiento que destaca el anuncio, y solo aparece en código muy avanzado.

Microsoft dedicará las próximas semanas a estabilidad y rendimiento. La versión candidata llegará en aproximadamente un mes y la definitiva poco después. Hasta entonces, la beta es para probarla en una rama aparte, no para producción.

Más fuentes: la versión 7.1 beta en GitHub y los cambios de atributos de importación, de tipos distribuidos y de content mappers. Portada: edificio 92 del campus de Microsoft en Redmond, foto de Coolcaesar, licencia CC BY-SA 4.0, Wikimedia Commons; logotipo de TypeScript, marca de Microsoft, Wikimedia Commons.

Fuente: Microsoft, «Announcing TypeScript 7.1 Beta», 20 de octubre de 2026