Inicio / Artículos

Comprobación versus ejecución: dónde encaja el compilador Go de TypeScript 7 en tu cadena de herramientas

Aprenda qué es lo que realmente acelera el compilador nativo de Go en TypeScript 7, por qué herramientas como Angular y typescript-eslint van a la zaga, y cómo separar la verificación de tipos de la ejecución.

Editor: REACTAPP.TOP14 min de lectura3257 palabras

Fuentes: TypeScript 7 Moved Its Compiler to Go. Here’s What Actually Changes

TypeScript 7 reemplaza el compilador autohospedado por una versión nativa escrita en Go, y las cifras presentadas son lo suficientemente elevadas como para generar confusión sobre qué es lo que realmente se vuelve más rápido. El JavaScript de producción no cambia en absoluto su velocidad; sí lo hacen el editor, las comprobaciones de tipo del proceso de integración continua y la compilación de los monorepos. Al mismo tiempo, Node, Bun y Vite han hecho que el compilador de TypeScript sea opcional para ejecutar y transformar código. Esta guía separa estos aspectos para que pueda decidir qué actualizar, qué esperar y cómo estructurar una cadena de herramientas en la que la verificación y la ejecución sean tareas distintas.

El alcance de TypeScript hace que sea importante hacerlo bien. En agosto de 2025, GitHub informó que TypeScript se había convertido en el lenguaje más utilizado por los contribuyentes mensuales, superando tanto a Python como a JavaScript, con más de 2.6 millones de personas contribuyendo al código en TypeScript cada mes. Un cambio en los cimientos de ese ecosistema tiene efectos en frameworks, linters, gestores de paquetes y editores, y no todos avanzan al mismo ritmo.

De un compilador autohospedado a uno nativo

Antes de la versión 7, tsc era un programa autoinicializable. Su código fuente era TypeScript; se compilaba a JavaScript, y ese JavaScript se ejecutaba en Node para analizar, verificar y procesar los proyectos de otros usuarios. La autohospedaje es una tradición respetable para los compiladores, y este diseño permitió que el lenguaje creciera exponencialmente durante una década. Sin embargo, su límite es el entorno de ejecución de JavaScript: un único hilo principal, un montón recolectado por basura que nunca se ajustó para manejar grandes estructuras en memoria de nodos sintácticos y tipos, además de formas limitadas de compartir esos datos entre procesos.

La respuesta de Microsoft fue una adaptación, no una reescritura. La base de código en Go refleja deliberadamente la estructura y el comportamiento de la implementación existente, por lo que se pretende que el sistema de tipos y sus semánticas permanezcan iguales. Lo que cambia es la base subyacente: código máquina nativo, hilos capaces de compartir memoria y mucho más espacio para ejecutar tareas en paralelo. Go fue una elección pragmática precisamente por esa razón; su modelo de memoria y su recolector de basura permiten al equipo traducir el código existente con estructuras de datos similares, en lugar de rediseñar todo según reglas de propiedad.

Los resultados de las pruebas publicadas muestran que las compilaciones completas típicas son de 8 a 12 veces más rápidas:

  • La base de código de VS Code pasa de 125.7 segundos con TypeScript 6 a 10.6 segundos con TypeScript 7.
  • La compilación completa de Playwright disminuye de 12.8 segundos a 1.47 segundos.
  • Al configurar ocho procesos de verificación de tipos, los tiempos vuelven a disminuir, a 7.51 segundos (VS Code) y 1.16 segundos (Playwright).
  • “TypeScript es diez veces más rápido” es un resumen preciso de esos valores. Sin embargo, también es fácil interpretarlo erróneamente, ya que no indica qué es lo que es diez veces más rápido.

    ¿Qué se vuelve más rápido y qué no?

    Tomemos un pequeño fragmento de código escrito: una interfaz y un objeto que la cumple.

    interface User {
      id: string;
      name: string;
    }
    const user: User = {
      id: '42',
      name: 'Arthur',
    };
    

    Sea cual sea la herramienta que lo compila, el navegador o el servidor terminan recibiendo JavaScript puro con la información de tipos eliminada:

    const user = {
      id: '42',
      name: 'Arthur',
    };
    

    El tiempo de ejecución no tiene idea de qué compilador procesó el código fuente, ni en qué lenguaje está implementado ese compilador. Solo ve el JavaScript generado, y esa salida es la misma que antes. Por lo tanto, reescribir tsc en Go no afecta en nada la velocidad de ejecución de su aplicación. Si una página es lenta o un manejador de API está limitado por la CPU, TypeScript 7 no cambiará eso.

    Los beneficios se perciben más temprano, durante el desarrollo, cuando TypeScript funciona constantemente: al cargar proyectos, calcular diagnósticos, ofrecer completados y buscar todas las referencias, monitorear archivos y volver a verificar la compilación en CI. Una medida ilustra bien esto: abrir un archivo con un error en el repositorio de VS Code solía tardar unos 17.5 segundos hasta que aparecía el primer diagnóstico; con TypeScript 7, ese tiempo es de menos de 1.3 segundos. El nuevo servidor de lenguaje está basado en el Language Server Protocol, puede utilizar múltiples hilos, y Microsoft también informa una cantidad mucho menor de comandos del servidor de lenguaje fallidos y caídas.

    Por lo tanto, el enfoque útil es este: la aplicación no se vuelve más rápida, pero trabajar en ella sí lo hace. En una gran base de código o monorepo, reducir los minutos necesarios para cada verificación de tipos y los segundos para cada diagnóstico del editor cambia el ciclo de retroalimentación con el que se trabaja todo el día. Eso representa un verdadero aumento de la productividad, aunque ningún usuario se dará cuenta nunca.

    El resto de las novedades de TypeScript 7

    El compilador nativo domina la conversación, pero varios subsistemas fueron reconstruidos en torno a él.

    Paralelismo que se puede ajustar

    El análisis sintáctico, la generación de código y partes de la verificación de tipos pueden ejecutarse en paralelo, y las compilaciones con referencia a proyectos permiten compilar varios proyectos al mismo tiempo, lo cual es especialmente importante en los monorepos. Puedes aumentar explícitamente la cantidad de procesos dedicados a la verificación de tipos:

    tsc --checkers 8
    

    O bien desactive por completo el paralelismo, en máquinas con limitaciones estrictas de recursos o cuando desea un comportamiento determinista durante la depuración:

    tsc --singleThreaded
    

    Una bandera separada --builders controla cuántas compilaciones de referencia al proyecto se ejecutan simultáneamente. Considérelas como ajustes finos y no como interruptores que activan “lo máximo posible”. Cada trabajador adicional ocupa su propia parte del programa en memoria, por lo que un ejecutor de CI con muchos núcleos pero poca RAM puede terminar siendo más lento o quedarse sin memoria si simplemente se asignan trabajadores según los núcleos. Mida el rendimiento en sus ejecutores reales antes de establecer una configuración.

    Un modo de vigilancia reconstruido

    --watch también fue reimplementado. El equipo primero intentó enfoques más convencionales multiplataforma disponibles en Go, pero monitorear el sistema de archivos resultó demasiado costoso para proyectos grandes. Al final, trasladaron las ideas del monitor de archivos en C++ de Parcel a Go y crearon un nuevo monitor diseñado para un mejor uso de recursos en diferentes sistemas operativos.

    Nuevas opciones predeterminadas y eliminación de opciones obsoletas

    TypeScript 7 mantiene los cambios de configuración introducidos durante la transición a TypeScript 6:

    • strict está activado por defecto.
    • La opción predeterminada para module ahora es esnext.
    • types comienza como un array vacío, por lo que los paquetes de tipos globales ya no se cargan automáticamente.
    • target: es5 ha sido eliminado.
    • La resolución de módulos clásica también ha sido eliminada.
  • Se han eliminado las salidas para módulos AMD y UMD.
  • baseUrl ya no está soportado.
  • Un tsconfig.json que no se ha modificado desde la época en que Internet Explorer era un factor importante en las implementaciones probablemente necesite atención. En particular, el cambio en types puede generar una serie de errores de tipo “no se puede encontrar el nombre” para variables globales de pruebas o funciones integradas de Node, hasta que se indiquen los paquetes en los que se depende. Si aún no has abordado estos valores predeterminados, nuestra guía práctica de migración a los valores predeterminados problemáticos de TypeScript 6.0 los trata en detalle, y las mismas soluciones son aplicables aquí.

    La pieza que falta: una API de compilador estable

    El detalle más importante es algo que TypeScript 7.0 no incluye: una API programática estable. Para muchos proyectos, esto es más relevante que cualquier flag o valor predeterminado, ya que determina si las herramientas relacionadas con el compilador pueden funcionar en absoluto.

    Por qué el ecosistema no puede cambiar de la noche a la mañana

    Invocar el compilador desde una terminal y crear una herramienta basada en él son relaciones muy diferentes. Muchos frameworks, herramientas del lenguaje y verificadores de código no se limitan a utilizar el binario directamente:

    tsc
    

    Cargan TypeScript como una biblioteca y le solicitan árboles sintácticos, tipos resueltos, respuestas del servicio de lenguaje y otros componentes internos del compilador. Se espera que la sustitución de esa API llegue en TypeScript 7.1, y hasta entonces Microsoft admite oficialmente la instalación simultánea de ambas versiones principales. En el momento de escribir esto, eso significa que muchos equipos utilizarán el compilador nativo para las verificaciones en la línea de comandos, mientras que sus integraciones con editores y herramientas de análisis seguirán utilizando la versión basada en JavaScript.

    Varias herramientas conocidas se ven afectadas:

    • La verificación de tipos en las plantillas de Angular está profundamente integrada con TypeScript, por lo que el soporte completo del editor de Angular debe seguir utilizando el servicio de lenguaje anterior por ahora.
    • Las herramientas para Vue, Astro, Svelte, MDX y otros formatos que incorporan TypeScript en otro tipo de archivo enfrentan limitaciones similares hasta que se lance la nueva API.

    Nada de esto constituye un defecto en el puerto. Así es como se ve una migración de una herramienta fundamental en un ecosistema real: el motor ya está listo antes de que todo lo conectado a él haya sido adaptado.

    Cuatro formas en que una herramienta puede depender de TypeScript

    typescript-eslint es una buena herramienta para comprender esto. ESLint en sí no está basado en el compilador de TypeScript, por lo que afirmar que “ESLint se volvió más rápido porque TypeScript pasó a usar Go” sería simplemente incorrecto. Sin embargo, typescript-eslint es el puente que permite a ESLint analizar la sintaxis de TypeScript y, en el caso de las reglas que tienen en cuenta los tipos, consultar la información de tipo de TypeScript. Su analizador actual sigue dependiendo de la API del compilador antiguo, aunque el proyecto ha estado experimentando con la implementación nativa. Los mantenedores claramente se están preparando, pero adoptar TypeScript 7 allí no es cuestión de simplemente aumentar un número de versión.

    Ese ejemplo pone de manifiesto una distinción que vale la pena tener en cuenta cada vez que alguien dice que una herramienta “usa TypeScript”. Existen al menos cuatro relaciones diferentes:

    • Escrita en TypeScript. El código fuente de la herramienta es en TypeScript. Se beneficia cuando sus mantenedores realizan comprobaciones de tipo y construyen más rápido, pero sus usuarios no perciben ningún cambio.
    • Ejecuta TypeScript. Entornos de ejecución como Node y Bun aceptan archivos .ts como entrada sin necesidad de utilizar tsc.
    • Transforma TypeScript. Los bundlers y transpiladores eliminan los tipos y reescriben la sintaxis, uno por uno.
    • Depende de las semánticas de TypeScript. Los linters con reglas que tienen en cuenta los tipos, los servicios de lenguaje de los frameworks y los editores necesitan que el compilador comprenda todo el programa.

    El puerto nativo cambia de manera diferente en cada categoría. Solo la última necesita la API del compilador, y es precisamente esa categoría la que debe esperar a 7.1.

    Un gestor de paquetes en plena migración

    pnpm muestra cómo interactúan estas categorías. Se trata de un gran monorepo en TypeScript con muchos paquetes, pruebas intensivas y una amplia analítica del editor, lo que en teoría lo convierte en un beneficiario ideal de TypeScript 7. Con el tiempo debería serlo. Mientras tanto, sus mantenedores también deben mantener funcionando typescript-eslint, y esa integración con el linter sigue estando vinculada a la interfaz del compilador legado. La cadena de dependencias se ve más o menos así:

    pnpm
      ↓
    typescript-eslint
      ↓
    TypeScript compiler API
      ↓
    TypeScript 6 — for now
    

    También es importante aclarar qué experimentarán los usuarios de pnpm. TypeScript 7 no hace que este comando sea más rápido:

    pnpm install
    

    La instalación de paquetes es el comportamiento en tiempo de ejecución de pnpm, y este funciona como JavaScript en Node, independientemente del compilador que haya revisado su código fuente. Lo que TypeScript 7 puede mejorar es la experiencia al desarrollar pnpm: la verificación de tipos, las ejecuciones en CI y otros flujos de trabajo impulsados por compiladores. Incluso esa mejora llega solo a la velocidad del eslabón más lento de su gráfico de dependencias. Un proyecto grande no puede adoptar un cambio fundamental más rápido que las herramientas de las que depende.

    Dónde los beneficios son inmediatos

    Los proyectos que solo necesitan el compilador como herramienta de verificación en la línea de comandos y un servidor de lenguaje pueden beneficiarse de inmediato. VS Code es el ejemplo más claro: una enorme base de código en TypeScript donde millones de desarrolladores utilizan las herramientas correspondientes a diario. Reducir el tiempo de compilación completo de más de dos minutos a aproximadamente diez segundos es algo significativo; acortar el tiempo de espera para la primera diagnosis del editor de unos diecisiete segundos a poco más de uno es algo que cualquiera puede percibir.

    Playwright, uno de los proyectos de referencia de Microsoft, pasa de 12.8 segundos a 1.47 segundos para una compilación completa con la configuración por defecto. Nuevamente, eso no significa que Playwright inicie Chromium más rápido; significa que el mantenimiento y la verificación del propio código de Playwright se realizan mucho más rápidamente. Dado que gran parte de las herramientas para desarrolladores están escritas en TypeScript, un mantenimiento más rápido de esas herramientas tiene un efecto positivo en todo el ecosistema.

    Vite ya trata la verificación y la transformación como tareas separadas

    Vite está escrito principalmente en TypeScript, pero cuando sirve o compila tu aplicación en TypeScript no llama al compilador de TypeScript para transpilar cada módulo. La versión moderna de Vite utiliza un pipeline de transformación dedicado y omite intencionalmente la verificación de tipos. Su documentación recomienda ejecutar TypeScript por separado, como una verificación puntual:

    tsc --noEmit
    

    o de forma continua durante el desarrollo:

    tsc --noEmit --watch
    

    El razonamiento es sólido. Para transformar un archivo solo se necesita ese archivo: eliminar las anotaciones, reescribir algunas estructuras y listo. La verificación de tipos requiere conocer todo el grafo de módulos, ya que un cambio en un archivo puede romper los acuerdos establecidos en otro. Realizar ambas tareas en el mismo paso obliga a la operación rápida a esperar a la lenta. Por lo tanto, un proyecto típico de Vite cuenta con dos rutas paralelas a partir de la misma fuente:

    ┌── Vite / Oxc ── transform ──> Browser
    TypeScript source ──┤
                        └── TypeScript ───── type-check
    

    Desde esta perspectiva, TypeScript 7 no necesita convertirse en el transformador de JavaScript más rápido, ya que Vite cuenta con una herramienta optimizada para ello. TypeScript puede centrarse en la tarea que requiere comprender todo el programa, y esa tarea ahora se realiza de manera drásticamente más rápida. Si utiliza esta configuración hoy en día, una consecuencia práctica es que un error de tipo no detiene el servidor de desarrollo; asegúrese de ejecutar tsc --noEmit en CI o en un gancho de pre-push para que los errores no pasen desapercibidos.

    Herramientas para JavaScript escritas en todo menos en JavaScript

    Existe una tendencia más amplia al respecto. La actual pipeline de compilación de Vite utiliza Rolldown, y tanto Rolldown como Oxc están escritos en Rust. esbuild eligió Go hace años. Bun implementa grandes partes de sí mismo en Zig. Ahora TypeScript se ha unido a ellos con Go.

    Eso no es una crítica a JavaScript. Las interfaces públicas siguen resultando naturales para los desarrolladores de JavaScript y TypeScript, mientras que el procesamiento intensivo en CPU para la análisis, resolución y otros pasos se ejecuta como código nativo. Cada capa tiene requisitos diferentes, y TypeScript 7 es el ejemplo más reciente y destacado de elegir el lenguaje de implementación según la capa.

    Runtimes que ejecutan TypeScript sin tsc

    Esa misma división también ocurre en el lado del runtime. El modelo mental tradicional de un proyecto TypeScript era una línea recta desde el código fuente, pasando por el compilador, hasta llegar a JavaScript y finalmente a Node:

    TypeScript
        ↓
       tsc
        ↓
    JavaScript
        ↓
      Node.js
    

    Los proyectos reales siempre han tenido más pasos, pero la idea central se mantenía: Node ejecutaba JavaScript, por lo que TypeScript tenía que convertirse primero en JavaScript. Hoy en día esto se puede hacer directamente:

    node server.ts
    

    El detalle importante es que Node no ejecuta el compilador de TypeScript. Su soporte integrado es intencionalmente mínimo: elimina la sintaxis de TypeScript que se puede borrar y ejecuta lo que queda. No realiza verificación de tipos, y la sintaxis que requiere generar JavaScript real (en lugar de simplemente eliminar anotaciones) queda fuera de ese modelo de eliminación. Una declaración tipada como esta:

    const port: number = 3000;
    

    en efecto se convierte en lo siguiente antes de la ejecución:

    const port = 3000;
    

    La palabra clave es “Erasable”. Constructos como enum, namespace con valores en tiempo de ejecución, o propiedades de parámetros de constructor generan JavaScript que no existía en el código fuente, por lo que la eliminación pura no puede manejarlos. TypeScript ofrece la opción del compilador erasableSyntaxOnly para marcar dichos constructos si se desea que el código siga siendo compatible con la eliminación de tipos; consulte la documentación actual de Node y TypeScript para conocer el comportamiento exacto en sus versiones.

    Esta capacidad también existía antes de Node 26, por lo que la ejecución directa de TypeScript no debería presentarse como una característica exclusiva de Node 26. Node 26 trae sus propios cambios, como Temporal habilitado por defecto, un V8 más reciente, otra importante actualización de Undici y la habitual limpieza que se realiza con cada versión principal, pero eso es un tema aparte. Lo importante para esta discusión es la dirección: Node trata cada vez más a TypeScript como un formato de entrada que puede consumir directamente, sin tener que solicitar primero a tsc que genere JavaScript.

    Bun trata a TypeScript como entrada normal

    Bun, que aún se encuentra en su línea 1.x, ha funcionado de esta manera desde sus inicios. Ejecutar un archivo TypeScript es simplemente:

    bun server.ts
    

    El cargador de Bun elimina y transforma la sintaxis de TypeScript antes de su ejecución utilizando sus propias herramientas. Y, una vez más, la transpilación no implica verificación de tipos. Por lo tanto, un flujo de trabajo perfectamente razonable en Bun consiste en dos comandos:

    tsc --noEmit
    bun server.ts
    

    El primero responde a la pregunta “¿Este programa satisface el sistema de tipos?”. El segundo responde “¿Puede ejecutarse este programa?”. Node moderno admite la misma separación:

    tsc --noEmit
    node server.ts
    

    En ambos casos, el tiempo de ejecución nunca espera al verificador de tipos, y el verificador de tipos nunca necesita generar archivos de salida. Tenga en cuenta que un proyecto ejecutado de esta manera no tiene una fase de compilación para detectar errores de tipo por casualidad; si la verificación no está integrada en CI, simplemente no ocurrirá.

    La función de TypeScript es centrarse en comprender los programas

    Durante años, el flujo de trabajo se redujo a un único proceso, donde el compilador se encontraba justo entre la escritura y ejecución del código:

    Write TypeScript
          ↓
    Compile TypeScript
          ↓
    Run JavaScript
    

    Las herramientas modernas cada vez se asemejan más a dos ramas provenientes de la misma fuente: una para comprender y verificar, y otra para transformar y ejecutar:

    ┌── TypeScript ── understand and check
    TypeScript source ────────┤
                              └── Runtime / bundler ── transform and execute
    

    Vite puede utilizar Oxc para transformar el código mientras tsc lo verifica. Node elimina por sí mismo la sintaxis eliminable. Bun cuenta con su propio cargador. Ninguna de estas herramientas necesita TypeScript 7, ni ningún tsc, para ejecutar tu aplicación. Esa es precisamente la razón por la que el compilador nativo sigue siendo importante: la responsabilidad más distintiva de TypeScript ya no es convertir rápidamente un archivo .ts en uno .js, tarea que otras herramientas ya realizan bien. Su verdadero valor radica en cuestiones relacionadas con todo el programa, como estas:

    • ¿Es este valor compatible con el contrato al que se le pasa?
    • ¿Algún refactorizado ha dañado a un componente de otro paquete?
    • ¿Es correcta esta restricción genérica?
    • ¿A qué se refiere este símbolo y dónde más se utiliza este tipo?
    • ¿Qué debería ofrecer el editor como completado justo aquí?

    Para satisfacer esas necesidades se requiere mucho más contexto que simplemente eliminar : string de una línea, y ese análisis del programa completo es precisamente lo que la versión para Go hace que sea drásticamente más rápida. Para conocer más sobre el funcionamiento de TypeScript de forma nativa en estas herramientas, consulte nuestra guía de migración al compilador de TypeScript para Go y su ejecución nativa.

    Puntos clave

    • TypeScript 7 es una adaptación del compilador existente a Go, no un rediseño del lenguaje; el JavaScript generado y el rendimiento en tiempo de ejecución de su aplicación permanecen sin cambios.
    • Las ventajas se notan durante el desarrollo: las compilaciones completas suelen ser de 8 a 12 veces más rápidas, los diagnósticos en el editor son mucho más veloces y el servidor del lenguaje es más estable.
  • Ajuste los parámetros --checkers, --builders y --singleThreaded según los límites reales de memoria del CI, en lugar de maximizar ciegamente el número de procesos.
  • Esté preparado para un período híbrido. Dado que no habrá una API de compilador estable hasta la versión 7.1, Angular, Vue, Svelte, Astro, las herramientas MDX y typescript-eslint podrían hacer que siga utilizando TypeScript 6 en algunas integraciones, y se permite ejecutar ambas versiones simultáneamente.
  • Efectúe una auditoría de tsconfig.json en busca de los nuevos valores predeterminados y de las opciones eliminadas (strict, module, types, objetivo ES5, resolución clásica, AMD/UMD, baseUrl).
  • Trate la verificación de tipos como un paso independiente. Vite, Node y Bun ejecutan o transforman TypeScript sin verificarlo, por lo que debe hacer de tsc --noEmit una parte obligatoria del proceso CI.
  • Lecturas relacionadas

  • Un repositorio central de configuración para microservicios: onboarding y sincronización con un solo comando — Crea un repositorio central de configuración con scripts de configuración, sincronización y actualización diaria para que todos los servicios NestJS y React compartan ajustes de linting, editor y Docker.
  • Dónde encaja Turborepo en un monorepo NestJS y cuándo oírlo pasar — Cómo Turborepo, los espacios de trabajo pnpm y NestJS dividen el trabajo en un monorepo de TypeScript: paquetes compartidos, gráficos de tareas, caché, riesgos de acoplamiento y cuándo oírlo pasar.