Anuncian TypeScript 7.0
(devblogs.microsoft.com)- TypeScript 7.0 es una versión que migra la cadena de herramientas a código nativo basado en Go y, en compilaciones completas de proyectos grandes, normalmente ofrece una mejora de velocidad de 8 a 12 veces
- El nuevo
tscse instala como antes mediante el paquetetypescriptde npm, y el soporte para editores funciona en VS Code, Visual Studio, WebStorm y otros mediante un servidor de lenguaje basado en LSP - En bases de código como
vscode,sentry,bluesky,playwrightytldraw, los tiempos de compilación se redujeron notablemente, y en algunos entornos también bajó el uso total de memoria - TypeScript 7.0 todavía no tiene una API de programación estable, por lo que las herramientas que integran TypeScript, como
typescript-eslint, Vue, MDX, Astro, Svelte y la verificación de tipos en plantillas de Angular, necesitan ejecutarse en paralelo con TypeScript 6.0 - Como hay nuevos valores predeterminados y opciones eliminadas, conviene aplicar primero los cambios de TypeScript 6.0 para facilitar la transición; está previsto que TypeScript 7.1 ofrezca la nueva API
TypeScript nativo basado en Go
- TypeScript 7.0 es un port nativo de la cadena de herramientas de TypeScript y usa una nueva base de código escrita en Go
- El port se hizo intentando conservar al máximo la estructura y la lógica de la base de código existente, con el objetivo de mantener la coherencia y compatibilidad de resultados entre ambos compiladores
- La nueva base de código logra compilaciones completas normalmente 8 a 12 veces más rápidas gracias a la velocidad del código nativo, el multithreading basado en memoria compartida y varias optimizaciones
- La instalación puede hacerse con npm, como antes
npm install -D typescript
- Después de instalarlo, se puede usar el nuevo ejecutable
tscen el workspace, y ejecutarlo connpx tsc
Reducción del ciclo de feedback de desarrollo
- TypeScript interviene en muchas etapas del desarrollo, como la carga del editor, buscar todas las referencias, autocompletado, diagnósticos,
tscy el modo--watch - TypeScript 7 reduce los tiempos de espera en todo este proceso y acorta el ciclo de feedback
- En la base de código de VS Code, el tiempo desde abrir un archivo con errores hasta que aparece el primer error bajó de aproximadamente 17.5 segundos a menos de 1.3 segundos, más de 13 veces más rápido
- El soporte para editores está basado en LSP, y el nuevo servidor de lenguaje aprovecha el multithreading para procesar solicitudes simultáneas con rapidez
- Los usuarios de VS Code pueden instalar la extensión dedicada para TypeScript 7, y en las próximas semanas VS Code también incorporará soporte para TypeScript 7
- La versión más reciente de Visual Studio activa automáticamente TypeScript 7 según el workspace
Rendimiento de compilación y resultados de memoria
- Los tiempos de compilación completa al comparar TypeScript 6 y 7 en grandes bases de código open source son los siguientes
| Base de código | TypeScript 6 | TypeScript 7 | Mejora de velocidad |
|---|---|---|---|
| vscode | 125.7 s | 10.6 s | 11.9 veces |
| sentry | 139.8 s | 15.7 s | 8.9 veces |
| bluesky | 24.3 s | 2.8 s | 8.7 veces |
| playwright | 12.8 s | 1.47 s | 8.7 veces |
| tldraw | 11.2 s | 1.46 s | 7.7 veces |
- En las mismas compilaciones, TypeScript 7 en general también tuvo un uso total de memoria menor
| Base de código | TypeScript 6 | TypeScript 7 | Cambio de memoria |
|---|---|---|---|
| vscode | 5.2 GB | 4.2 GB | -18% |
| sentry | 4.9 GB | 4.6 GB | -6% |
| bluesky | 1.8 GB | 1.3 GB | -26% |
| playwright | 1.0 GB | 0.9 GB | -11% |
| tldraw | 0.6 GB | 0.5 GB | -15% |
Validación en bases de código reales y feedback de equipos
- El proyecto TypeScript ejecuta decenas de miles de pruebas acumuladas durante más de 10 años en cada commit de la rama
main - Además de esas pruebas, TypeScript 7 fue validado en bases de código reales de grandes equipos internos y externos
- Dentro de Microsoft, los equipos de Loop, Office, PowerBI, Teams y Xbox validaron TypeScript 7
- Externamente, Bloomberg, Canva, Figma, Google, Lattice, Linear, Miro, Notion, Sentry, Slack, Vanta, Vercel, VoidZero y otros lo probaron en sus bases de código y dieron feedback
- El nuevo servidor de lenguaje redujo en más de 80% los comandos fallidos del servidor de lenguaje y en más de 60% los crashes del servidor frente a TypeScript 6.0
- El feedback de equipos reales incluye estos casos
- Slack informó que con TypeScript 7 el tiempo de la merge queue se redujo 40% y que el tiempo de verificación de tipos en CI bajó de unos 7.5 minutos a 1.25 minutos
- Vanta observó en uno de sus proyectos grandes una mejora de velocidad de compilación de hasta 9 veces
- El equipo de Microsoft News Services redujo en 400 horas mensuales el tiempo de espera de compilaciones de CI
- Canva informó que el tiempo hasta ver el primer error en el editor bajó de unos 58 segundos a 4.8 segundos
Ejecución en paralelo con TypeScript 6.0
- TypeScript 7.0 todavía no incluye una API
- Está previsto que TypeScript 7.1 ofrezca una API nueva y diferente
- Hasta entonces, para herramientas que necesitan acceso programático al compilador, se puede ejecutar TypeScript 6.0 en paralelo con TypeScript 7.0
- El nuevo paquete de compatibilidad
@typescript/typescript6proporciona el ejecutabletsc6y vuelve a exportar la API de TypeScript 6.0 - Para herramientas que importan
typescriptdirectamente como peer dependency, comotypescript-eslint, se recomienda usar un alias de npm
npm install -D typescript@npm:@typescript/typescript6
- Para usar juntas la API de TypeScript 6 y el
tscde TypeScript 7, se puede definir un alias como el siguiente
{
"devDependencies": {
"@typescript/native": "npm:typescript@^7.0.2",
"typescript": "npm:@typescript/typescript6@^6.0.2"
}
}
- El paquete existente
@typescript/native-previewvenía ofreciendo builds nightly de la nueva base de código de TypeScript 7, y tenía más de 8.5 millones de descargas semanales - En adelante, los builds nightly se reanudarán con la etiqueta
nextdel paquete estándartypescript
npm install -D typescript@next
Opciones para controlar la paralelización
-
TypeScript 7.0 ejecuta en paralelo varias etapas, como parsing, verificación de tipos y emit
-
El parsing y el emit son fáciles de ejecutar de forma independiente por archivo, por lo que escalan con relativamente poca sobrecarga en bases de código grandes
-
Las nuevas flags experimentales
--checkers,--buildersy--singleThreadedajustan el comportamiento de paralelización -
--checkers- TypeScript 7.0 crea una cantidad fija de workers de verificación de tipos y, para los mismos archivos de entrada, siempre divide el trabajo de la misma manera para producir resultados idénticos
- La cantidad predeterminada de workers de verificación de tipos es 4, y se puede ajustar con
--checkers - Los resultados en la misma máquina usando
--checkers 8son los siguientes
Base de código TypeScript 6 TypeScript 7 --checkers 8Mejora de velocidad vscode 125.7 s 7.51 s 16.7 veces sentry 139.8 s 12.08 s 11.6 veces bluesky 24.3 s 2.01 s 12.1 veces playwright 12.8 s 1.16 s 11 veces tldraw 11.2 s 1.06 s 10.6 veces -
Aumentar
--checkerspuede acelerar la build al aprovechar más núcleos de CPU, pero normalmente viene acompañado de un mayor uso de memoria- En CI runners con pocos núcleos de CPU y poca memoria, se puede bajar el valor para evitar overhead innecesario
--checkers 1hace que la verificación de tipos sea, en la práctica, de un solo hilo y elimina trabajo duplicado- En casos raros, cambiar la cantidad de
--checkerspuede revelar resultados dependientes del orden, por lo que puede ayudar especificar una cantidad fija de checkers en todo el entorno de build
-
--builders--builderscontrola la cantidad de builders de referencias de proyecto que pueden ejecutarse al mismo tiempo al correr--build- Puede ser especialmente útil en monorepos con muchos proyectos
- Aumentar el valor puede acelerar la build, pero también puede incrementar el uso de memoria
- Tiene un efecto multiplicativo con
--checkers, por lo que--checkers 4 --builders 4puede ejecutar hasta 16 verificadores de tipos al mismo tiempo - A diferencia de
--checkers, cambiar la cantidad de--buildersno debería producir resultados distintos - Las builds con referencias de proyecto están, por defecto, limitadas por el grafo de dependencias del proyecto
-
--singleThreaded--singleThreadedhace que todo el compilador se ejecute en un solo hilo- Puede ser útil para depuración, comparación de rendimiento entre TypeScript 6 y 7, orquestación externa de builds paralelas y entornos con recursos muy limitados
- Esta flag no solo limita a 1 la cantidad de workers de verificación de tipos, sino que también hace que el parsing y el emit se realicen en un solo hilo
Nuevo modo --watch
- TypeScript 7 rehizo por completo el modo
--watch - El nuevo
--watchse basa en el file-watcher de Parcel bundler para ofrecer monitoreo de archivos multiplataforma eficiente y confiable - La biblioteca estándar de Go no tiene una API integrada de monitoreo de archivos, y las bibliotecas de terceros evaluadas tenían problemas de confiabilidad, rendimiento, soporte multiplataforma e integración con herramientas de build
- Un enfoque de polling puro funcionaba en varios sistemas operativos, pero en proyectos grandes con muchas dependencias en
node_modulestenía un costo computacional alto - El equipo de TypeScript portó a Go
@parcel/watcher, usado en VS Code, y utiliza un shim mínimo en assembly para evitar depender de un toolchain de C++ - Este watcher es un paquete independiente y, en el modo
--watchde TypeScript 7, aporta mejoras en el uso de recursos en todas las plataformas
Valores predeterminados de TypeScript 6.0 y cambios de compatibilidad
- TypeScript 7.0 está diseñado para ser compatible con la verificación de tipos y el comportamiento de línea de comandos de TypeScript 6.0
- El código que compila limpiamente con TypeScript 6.0 con la flag
stableTypeOrderingactivada y sinignoreDeprecationsconfigurado debería compilar igual en TypeScript 7.0 - TypeScript 7.0 adopta los nuevos valores predeterminados de TypeScript 6.0 y produce hard errors para flags y sintaxis deprecadas en TypeScript 6.0
- Los principales cambios en los valores predeterminados de configuración son los siguientes
- El valor predeterminado de
strictestrue - El valor predeterminado de
moduleesesnext - El valor predeterminado de
targetes la versión estable actual de ECMAScript inmediatamente anterior aesnext - El valor predeterminado de
noUncheckedSideEffectImportsestrue - El valor predeterminado de
libReplacementesfalse - El valor predeterminado de
stableTypeOrderingestruey no se puede desactivar - El valor predeterminado de
rootDires./ - El valor predeterminado de
typeses[], y el comportamiento anterior se puede restaurar con["*"]
- El valor predeterminado de
- Los cambios en
rootDirytypesse consideran los que más pueden sorprender- Los proyectos cuyo
tsconfig.jsonestá fuera de un directorio de código fuente comosrcdeben especificarrootDirpara conservar la estructura de directorios existente - Los proyectos que dependen de declaraciones globales específicas deben indicar en
typeslos paquetes@typesnecesarios
- Los proyectos cuyo
{
"compilerOptions": {
"rootDir": "./src"
},
"include": ["./src"]
}
{
"compilerOptions": {
"types": ["node", "jest"]
}
}
Comportamientos eliminados o convertidos en hard error
- En TypeScript 7.0 ya no se admiten varias opciones y sintaxis deprecadas en TypeScript 6.0
- Los principales puntos son los siguientes
target: es5no está soportadodownlevelIterationno está soportadomoduleResolution: node/node10no está soportado; se recomiendanodenextybundlermodule: amd, umd, systemjs, noneno está soportado; se recomiendaesnextopreservejunto con bundler o resolución de módulos basada en navegadorbaseUrlno está soportado;pathspuede actualizarse a rutas relativas desde la raíz del proyecto en lugar debaseUrlmoduleResolution: classicno está soportado; se recomiendabundleronodenextesModuleInteropyallowSyntheticDefaultImportsno pueden configurarse comofalsealwaysStrictse consideratruey no puede configurarse comofalse- No se puede usar la palabra clave
moduleen declaraciones de namespace - No se puede usar la palabra clave
assertsen imports; se debe usarwithpara alinearse con el cambio de sintaxis de import attributes de ECMAScript - Bajo
skipDefaultLibCheck, la directiva/// <reference no-default-lib />ya no se respeta - Si hay un
tsconfig.jsonen el directorio actual, la build desde línea de comandos no puede recibir rutas de archivos y se requiere--ignoreConfigexplícito
Cambios en tipos de template literals y soporte de JavaScript
- TypeScript 7.0 maneja de forma más natural los code points Unicode en la inferencia de tipos de template literals
type HeadTail<S> = S extends `${infer Head}${infer Tail}` ? [Head, Tail] : never;
type Result = HeadTail<"😀abc">;
// 7.0: ["😀", "abc"]
// 이전: ["\ud83d", "\ude00abc"]
- Antes, siguiendo el comportamiento de indexación UTF-16 de JavaScript,
"😀"se dividía en las dos partes del surrogate pair - El nuevo comportamiento coincide con la intuición de tratar
"😀"como una sola unidad, como enfor...ofo[...str] - Puede ser un breaking change para manipulaciones de strings a nivel de tipos que modelaban intencionalmente code units UTF-16
- El soporte de JavaScript se rediseñó para ser más consistente con la forma en que se analizan los archivos TypeScript
- No se pueden usar valores en posiciones de tipo; se debe usar
typeof someValue @enumya no recibe un tratamiento especial- Un
?solo no puede usarse como tipo; se debe usarany @classno convierte una función en constructor; se debe usar una declaraciónclass- No se admite el
!postfix - Los nombres de tipo deben definirse dentro de etiquetas
@typedef - La sintaxis de funciones estilo Closure ya no está soportada; se debe usar la sintaxis abreviada de TypeScript
- No se pueden usar valores en posiciones de tipo; se debe usar
- Algunos patrones de JavaScript, como aliasing de
thisy reasignación completa delprototypede una función, ya no reciben tratamiento especial - Las diferencias entre TypeScript 6.0 y 7.0 se están documentando con más detalle en
CHANGES.md
Funciones y limitaciones del editor
- TypeScript 7.0 agrega varias funciones del editor que faltaban desde la beta
- Incluye imports automáticos, hovers extensibles, inlay hints, code lens, go-to-source-definition, edición vinculada de JSX, completado de etiquetas y más
- También incorpora funciones que no estaban en la beta de TypeScript 7.0, como semantic highlighting, “sort imports” y “remove unused imports”
- Para mejorar la calidad del servidor de lenguaje, se reconstruyó la infraestructura de pruebas y diagnóstico, y ahora es posible realizar fuzz testing contra las principales bases de código TypeScript y JavaScript de GitHub
Restricciones actuales de los flujos de trabajo con lenguajes integrados
- Es probable que los flujos de trabajo que usan Vue, MDX, Astro, Svelte y otros todavía no puedan aprovechar TypeScript 7
- También es probable que la verificación de tipos en plantillas especiales, como las plantillas de Angular, no pueda usar TypeScript 7
- La razón principal es que TypeScript 7 todavía no expone una API de programación estable
- Herramientas como Volar, que integran TypeScript en su propio compilador y servicio de lenguaje, por ahora no tienen otra opción que depender de TypeScript 6.0
- El equipo de TypeScript considera que este problema es una restricción puntual y planea colaborar con los mantenedores de esos proyectos para asegurar la compatibilidad con TypeScript 7
- Hasta entonces, se recomienda usar TypeScript 7 en escenarios que no requieran un plugin del language server
- Los proyectos de Angular pueden usar
tscde TypeScript 7 en la CLI para detectar rápidamente errores en todo el proyecto, y usar TypeScript 6.0 en paralelo para el soporte en el editor - Vue, MDX, Astro, Svelte y otros deberán seguir usando TypeScript 6.0 por el momento
- En VS Code, se puede volver a TypeScript 6.0 con el comando “Disable TypeScript 7 Language Server”
Planes a futuro
- El lanzamiento de TypeScript 7.0 es un hito importante del port nativo en el que el proyecto TypeScript se enfocó durante más de un año
- Después de la versión 7.0, el equipo planea retomar el trabajo en nuevas funciones, mejoras de usabilidad, mejoras adicionales de rendimiento y la implementación de nuevas API para el ecosistema
- Se espera que, de forma similar a antes de TypeScript 7.0, haya lanzamientos con nuevas funciones cada 3 a 4 meses
- TypeScript 7.1 está previsto para cerrar brechas que ayuden a la transición de la comunidad y para ofrecer nuevas API
2 comentarios
Opiniones en Hacker News
Según sus propias pruebas, las mejoras de velocidad de TypeScript 7 son las siguientes
Es impresionante que el equipo haya logrado resultados así mientras hacía la migración de forma responsable. Bun debería observar y aprender un poco. Lo que me da curiosidad es qué impacto tendrá en herramientas de nivel inferior que tienen que compilar codebases de TypeScript, como tsdown o esbuild, y si TS 7 se puede usar junto con el tsdown actual
--isolatedDeclarations; si no, basta con instalar TypeScript 6 en paralelo como indica el blogHubo una época en la que se discutía que los tipos no valían el esfuerzo que requerían. Lo bueno de TypeScript es, ante todo, que popularizó los tipos
Por ejemplo, varias veces escuché cosas como que Python no servía porque no tenía tipos, pero eso no tiene sentido. Python es un lenguaje fuertemente tipado y, al mismo tiempo, de tipado dinámico.
También hay lenguajes que realmente no tienen tipos, o que normalmente son “tipados con strings” (stringly typed). AREXX, que usé de chico, tenía todos los valores como strings aunque parecieran números, y la mayoría de las herramientas de Unix CLI como sed también pueden verse así. Pero la mayor parte de las discusiones sobre tipos giraba alrededor de lenguajes de tipado dinámico como Python, y casi no vi a nadie decir que los lenguajes de tipado débil o sin tipos fueran buenos para proyectos grandes. Más bien escuché mucho que a Python se lo llamaba erróneamente “sin tipos” y que por eso no podía usarse en proyectos grandes, algo que me resultaba confuso porque yo estaba construyendo proyectos grandes con Python
Antes, la exposición a los tipos venía sobre todo de C++/Java, y en particular C++ difícilmente puede ser un buen ejemplo de algo que no sea cómo crear un lenguaje excesivamente complejo. Una vez que ves tipos bien aplicados, es mucho más fácil convencerte
Lo realmente impresionante aquí es un gran equipo que mantuvo simultáneamente dos codebases separadas para el sistema de tipos más avanzado conocido por la humanidad. También espero con ganas la reescritura en Rust
Rust llevaría mucho más tiempo de desarrollo. Aunque Rust pudiera ser 20% más rápido que Go, la mejora obtenida al pasar de TypeScript a Go ya es suficientemente grande. En vscode, quizás con Rust se obtendría 14x en lugar de 11x con Go, pero Go por sí solo ya alcanza para marcar una gran diferencia
No quiero menospreciar el sistema de tipos de TypeScript; de hecho, es un trabajo muy interesante
Después de usar TypeScript durante algunos años, en Python se siente realmente engorroso tener que agregar anotaciones de tipo a mano y traer funcionalidades básicas del lenguaje como
abcEs interesante, pero ahora que Node elimina de forma nativa las anotaciones de tipo de TypeScript, casi no ejecuto TSC. Solo lo corro cuando necesito confirmar mediante la salida estática del compilador qué partes no pude actualizar después de introducir un gran cambio con regresiones
Incluso para el código frontend que irá al navegador dependo de la eliminación de tipos de Node
Me alegra que la sintaxis de tipos de JSDoc siga recibiendo atención. Es mi forma favorita de usar TypeScript en proyectos personales. Algunos cambios de sintaxis serán molestos de actualizar, pero la mayoría parece ir en una mejor dirección
[1] https://learn.microsoft.com/en-us/dotnet/csharp/language-ref...
Un gran dolor de TypeScript es que resulta difícil ajustar el alcance de la configuración de tsconfig, como
libytypes, para partes de un proyecto.El proyecto es una app web, pero por
vite.config.ts, Playwright y las pruebas unitarias, los tipos de Node terminan entrando en las herramientas del IDE. Aunque agregues una API de Node a un componente de React,tscno se queja.Actualmente, para aislar la biblioteca DOM de la biblioteca de Node, hace falta un espagueti de referencias de proyecto, un montón de archivos
tsconfig.jsony archivos de salidatsbuildinfo, y también es engorroso evitar la salida de tipos al usar referencias de proyecto.Incluso para una sola aplicación prefiero nx, y muevo el código compartido a una “biblioteca”. Uso bibliotecas que no se compilan, y en proyectos grandes funciona bastante bien.
Todavía no hay una API del compilador de TypeScript, pero dicen que están trabajando en eso, así que promete.
Al ver los gráficos donde el uso de memoria baja y el rendimiento sube mucho, me hace pensar si en el servidor no habría que usar Go en lugar de TypeScript.
Y, con las opciones que existen hoy, no termino de entender por qué alguien iniciaría un proyecto nuevo en TS/JS/Python.
Felicitaciones al equipo de TypeScript. Tendría material para una publicación larga o un audio, pero en pocas palabras, el ecosistema JavaScript/TypeScript es parecido a trabajar con madera.
Puedes hacer cosas tipo Ikea, de madera laminada barata y cartón. En código, sería una app de vibe coding sin originalidad.
Por otro lado, también puedes hacer muebles artesanales de alta gama o rascacielos de madera. Algo como usar madera joven y, con uniones a medida y técnicas de laminación, crear vigas resistentes al fuego. En el ecosistema JavaScript/TypeScript también pueden salir resultados de alta calidad, usando la IA como una potente máquina-herramienta, pero con artesanía. Si tienes el valor de construir algo y ponerlo en marcha, basta con adoptar el ecosistema TypeScript/JavaScript.
Opiniones en Lobste.rs
Entiendo la razón, pero me parece interesante que hayan pasado de un compilador self-hosted a uno que no lo es
Normalmente casi siempre pasa al revés, así que es un cambio poco común
El self-hosting mete una presión fuerte para que el lenguaje evolucione hacia uno que sirva mejor para escribir compiladores, y eso no siempre necesariamente es la dirección correcta
Aunque no programes en TypeScript, VSCode en sí está escrito en TypeScript, así que me pregunto si esta mejora también afecta la velocidad de VSCode
O si solo afecta a la extensión de lenguaje de TypeScript
Lo que se acelera aquí es únicamente el compilador que toma código TypeScript y lo convierte en JavaScript, y ese proceso ocurre en el pipeline de build antes de que Microsoft distribuya el ejecutable de VSCode
Una posible excepción es que el servidor LSP de TypeScript también podría volverse más rápido, porque efectivamente parsea código TypeScript en tiempo de ejecución. Pero eso es aparte del hecho de que VSCode esté escrito en TypeScript
tsctiene el principio de no tocar el código que procesa salvo lo mínimo, como eliminar tipos, así que hay bastantes cosas marcadas como WONTFIXPor eso esperaría que las características de rendimiento de las herramientas hechas con TypeScript casi no cambien
Un tip pequeño que saqué en lo personal. El proyecto que llevo ahora usa TS 5, pero como era de esperarse no quería usar eso en nvim
Así que primero instalé TS 7 con mise y luego creé un enlace simbólico
tsgodentro denode_modules/.binque apunta al TS instalado con miseComo nvim-lspconfig todavía usa el viejo nombre de archivo
tsgode la época de technical preview, nvim termina ejecutando el TS 7 que instalé en lugar del TS local