Anuncian TypeScript 6.0
(devblogs.microsoft.com)- Último lanzamiento basado en la base de código actual en JavaScript y versión puente para preparar la transición a TypeScript 7.0, el port nativo escrito en Go
- Incluye mejoras en inferencia de tipos y resolución de módulos, como la reducción de sensibilidad al contexto para funciones que no usan
thisy soporte para subpath imports que comienzan con#/ - Modernización importante de los valores predeterminados de opciones del compilador, como
strictpor defecto entrue,targetpor defecto enes2025ytypespor defecto en[] - Desaprobación masiva de opciones legacy, como target ES5, módulos AMD/UMD/SystemJS,
--baseUrly--moduleResolution node10 - Se añade soporte de tipos para propuestas modernas de ECMAScript Stage 4 como la API Temporal,
getOrInsert/getOrInsertComputedde Map yRegExp.escape
La posición de TypeScript 6.0
- Es el último lanzamiento basado en la base de código actual en JavaScript, y funciona como puente para la transición a TypeScript 7.0 (port nativo en Go)
- TypeScript 7.0 aprovecha código nativo y multithreading con memoria compartida, y ya está muy cerca de estar terminado
- La mayoría de los cambios de 6.0 están pensados para alinear y preparar la adopción de 7.0
- TypeScript 7.0 ya puede probarse anticipadamente mediante la extensión de VS Code o el paquete npm
Cambios desde la Beta y la RC
- Ajuste del type checking de expresiones de función en llamadas genéricas, especialmente en expresiones JSX genéricas — detecta más bugs en código existente, pero algunas llamadas genéricas podrían requerir argumentos de tipo explícitos
- También se aplica en llamadas
import()la extensión de la desaprobación de la sintaxis de import assertion (assert) - Actualización de tipos del DOM — refleja los estándares web más recientes, incluyendo ajustes relacionados con la API Temporal
Reducción de sensibilidad al contexto para funciones que no usan this
- Durante la inferencia de tipos, TypeScript clasifica funciones con parámetros sin tipo explícito como funciones sensibles al contexto (contextually sensitive function) y las procesa con menor prioridad en el orden de inferencia
- Las funciones escritas con sintaxis de método tenían un parámetro implícito
this, por lo que a diferencia de las arrow functions siempre se trataban como sensibles al contexto- Esto provocaba casos en los que la inferencia de tipos fallaba según el orden de los métodos dentro de un objeto literal
- En TypeScript 6.0, las funciones donde
thisno se usa realmente ya no se consideran sensibles al contexto- Estas funciones pasan a tener mayor prioridad en la inferencia de tipos, permitiendo inferencia correcta sin importar el orden de los métodos
- Implementado gracias a una contribución de Mateusz Burzyński
Soporte para Subpath Imports que comienzan con #/
- La funcionalidad de subpath imports de Node.js permite definir aliases para módulos internos de un paquete mediante el campo
importsenpackage.json - Antes, era obligatorio que después de
#hubiera un carácter, así que no se podían usar rutas que empezaran con#/- Esto causaba confusión entre desarrolladores acostumbrados a la convención de prefijo
@/en bundlers
- Esto causaba confusión entre desarrolladores acostumbrados a la convención de prefijo
- Recientemente, Node.js empezó a soportar subpath imports que comienzan con
#/- Ahora es posible un mapeo conciso como
"#/*": "./dist/*"
- Ahora es posible un mapeo conciso como
- TypeScript 6.0 lo soporta con las opciones
--moduleResolution nodenextybundler - Implementado gracias a una contribución de magic-akari
Se permite la combinación --moduleResolution bundler y --module commonjs
- Antes,
--moduleResolution bundlersolo podía usarse con--module esnexto--module preserve - Debido a la desaprobación de
--moduleResolution node(node10), esta nueva combinación es la ruta de actualización más adecuada para muchos proyectos - A largo plazo, se recomienda migrar a
--module preserve+--moduleResolution bundlero a--module nodenext
Flag --stableTypeOrdering
- Los type ID asignados internamente a los tipos en TypeScript dependen del orden de procesamiento, y en base a eso se ordenan los union types
- Esto puede generar comportamientos impredecibles donde el resultado emitido de declaraciones cambia según el orden de declaración
- TypeScript 7.0 introducirá type checking en paralelo, así que para resolver el problema de asignación no determinista de IDs usará un algoritmo de ordenamiento determinista basado en el contenido
- Ejemplo:
100 | 500siempre se emitirá en el mismo orden
- Ejemplo:
- Si se activa
--stableTypeOrderingen 6.0, el comportamiento de ordenamiento de tipos coincide con el de 7.0, reduciendo diferencias entre ambas bases de código- Puede haber una caída de rendimiento de hasta 25% en type checking
- Si aparecen errores de tipos por diferencias en inferencia, se puede resolver agregando argumentos de tipo explícitos o anotaciones de variables
- Es un flag pensado solo para diagnosticar migraciones de 6.0 a 7.0; no se recomienda usarlo a largo plazo
Opción es2025 (target y lib)
- ES2025 no trae nuevas funciones del lenguaje JavaScript, pero sí agrega tipos para APIs built-in como
RegExp.escape Promise.try, métodos deIteratory métodos deSetque estaban enesnextpasan aes2025- Implementado gracias a una contribución de Kenta Moriuchi
Soporte de tipos para la API Temporal
- TypeScript 6.0 incluye los tipos built-in de la propuesta Temporal, que ya llegó a Stage 4
- Puede usarse con
--target esnexto"lib": ["esnext"](o bien con el granularesnext.temporal) - APIs como
Temporal.Now.instant().subtract()y.add()pueden usarse con seguridad de tipos - Ya está disponible en varios runtimes y, al llegar a Stage 4, ya forma parte oficial del lenguaje JavaScript
- Implementado gracias a una contribución de Renegade334
Soporte de tipos para los métodos “upsert” de Map (getOrInsert / getOrInsertComputed)
- Simplifica el patrón repetitivo de verificar si existe una clave en un Map y, si no existe, establecer un valor predeterminado
- La propuesta “upsert” de ECMAScript llegó a Stage 4 y agrega dos nuevos métodos a
MapyWeakMapgetOrInsert: si la clave no existe, inserta y devuelve el valor predeterminado indicadogetOrInsertComputed: cuando crear el valor predeterminado es costoso, lo calcula de forma diferida mediante un callback- El callback recibe la clave como argumento, por lo que también sirve para generar valores predeterminados basados en la clave
- Se añadió a
esnextlib, así que puede usarse de inmediato en TypeScript 6.0 - Implementado gracias a una contribución de Renegade334
RegExp.escape
- La función
RegExp.escape, que escapa caracteres especiales dentro de expresiones regulares, llegó a Stage 4 - Está incluida en
es2025lib y puede usarse en TypeScript 6.0 - Implementado gracias a una contribución de Kenta Moriuchi
Integración de dom.iterable y dom.asynciterable en dom lib
- Antes, para usar iteración en
NodeList,HTMLCollection, etc., había que declarar explícitamente"lib": ["dom", "dom.iterable"] - En TypeScript 6.0, el contenido de
lib.dom.iterable.d.tsylib.dom.asynciterable.d.tsqueda integrado por completo enlib.dom.d.tsdom.iterableydom.asynciterablesiguen pudiendo referenciarse, pero ahora son archivos vacíos
- Como todos los navegadores modernos importantes soportan esta funcionalidad, es una mejora de conveniencia que elimina un punto común de confusión
Principales cambios en valores predeterminados
strictpor defecto entrue: como la mayoría de los proyectos nuevos quieren strict mode, los proyectos que dependían delfalseanterior deberán configurar explícitamente"strict": falsemodulepor defecto enesnext: refleja que ESM se volvió el formato de módulos dominantetargetpor defecto en la versión más reciente de ES (actualmentees2025): con runtimes evergreen generalizados, ya no hace falta transpilar a versiones viejasnoUncheckedSideEffectImportspor defecto entrue: ayuda a detectar errores tipográficos en imports usados solo por sus efectos secundarioslibReplacementpor defecto enfalse: mejora el rendimiento base evitando fallas innecesarias de resolución de módulos y aumentando menos el conjunto de archivos observados
rootDir cambia su valor predeterminado a .
- Antes, si no se especificaba, se infería a partir del directorio común de todos los archivos de entrada no declarativos
- Esto implicaba que para determinar si un archivo pertenecía al proyecto había que cargar y parsear ese proyecto
- En TypeScript 6.0, el valor predeterminado queda fijo en el directorio donde está
tsconfig.json - Si los archivos fuente están en una ubicación más profunda que
tsconfig.json, habrá que configurar explícitamente algo como"rootDir": "./src"- Si no se hace, puede generarse una estructura de salida no deseada, como
./dist/src/index.js
- Si no se hace, puede generarse una estructura de salida no deseada, como
types cambia su valor predeterminado a []
- Antes, se incluían automáticamente todos los paquetes dentro de
node_modules/@types, lo que generaba una gran sobrecarga en tiempo de build- En repositorios típicos, es común que cientos de paquetes
@typesqueden incluidos transitivamente
- En repositorios típicos, es común que cientos de paquetes
- En TypeScript 6.0, el valor predeterminado cambia a
[](arreglo vacío), evitando cargar archivos de declaraciones innecesarios - Se observaron mejoras reales de 20% a 50% en tiempo de build
- En la mayoría de los proyectos, será necesario configurar explícitamente algo como
"types": ["node"]o"types": ["node", "jest"]- El comportamiento anterior puede restaurarse con
"types": ["*"]
- El comportamiento anterior puede restaurarse con
Elementos desaprobados (Deprecation)
Desaprobación de target: es5
- El target ES5 casi ya no tiene casos de uso tras el retiro de IE y la generalización de navegadores evergreen
- El target mínimo pasa a ser ES2015, y si se necesita salida ES5 se recomienda usar un compilador externo
Desaprobación de --downlevelIteration
- Solo tenía efecto en el emit de ES5, así que pierde su razón de ser con la desaprobación del target ES5
Desaprobación de --moduleResolution node (node10)
- Reflejaba el algoritmo de resolución de módulos de Node.js 10, y ya no coincide con el comportamiento actual de Node.js
- Se recomienda migrar a
nodenext(si apuntas directamente a Node.js) o abundler(si usas bundlers/Bun)
Desaprobación de valores de módulo AMD, UMD y SystemJS
--module amd,--module umd,--module systemjsy--module nonedejan de estar soportados- Como ESM ya se soporta de forma general tanto en navegador como en Node.js, hay que migrar a un bundler o a un target ESM
Desaprobación de --baseUrl
- Se usaba principalmente como prefijo de
paths, pero también funcionaba como raíz de búsqueda en resolución de módulos, causando problemas de resolución inesperados - La migración consiste en quitar
baseUrly agregar el prefijo directamente en las entradas depaths- Ejemplo:
"@app/*": ["app/*"]→"@app/*": ["./src/app/*"]
- Ejemplo:
Desaprobación de --moduleResolution classic
- Era el algoritmo original de resolución de módulos de TypeScript, pero hoy todos los casos prácticos pueden reemplazarse por
nodenextobundler
Desaprobación de esModuleInterop false y allowSyntheticDefaultImports false
- Ya no será posible poner ambas opciones en
false, por lo que el comportamiento seguro de interop quedará siempre activado - Será necesario ajustar casos como
import * as express from "express"→import express from "express"
Desaprobación de --alwaysStrict false
- Todo el código pasa a considerarse JavaScript strict mode, por lo que código que use
await,static,private, etc. como identificadores normales deberá renombrarlos
Desaprobación de outFile
- Era una función para combinar múltiples archivos de entrada en uno solo, pero fue reemplazada por bundlers externos como Webpack, Rollup, esbuild y Vite
- La decisión busca concentrar a TypeScript en su rol principal: type checking y declaración de tipos emitida
Desaprobación de la sintaxis legacy module (declaraciones de namespace)
- La sintaxis
module Foo { ... }queda fuertemente desaprobada, y ahora debe usarsenamespace Foo { ... } - Las declaraciones de módulos ambient como
declare module "some-module" { ... }siguen estando soportadas - El objetivo es evitar conflictos con la propuesta de bloques
modulede ECMAScript
Desaprobación de la palabra clave import asserts
- Hay que cambiar
import ... asserts { type: "json" }porimport ... with { type: "json" } - Esto responde al cambio de la propuesta de import assertions hacia la propuesta de import attributes (palabra clave
with)
Desaprobación de la directiva no-default-lib
/// <reference no-default-lib="true"/>deja de estar soportado; se recomienda usar--noLibo--libReplacement
Error al indicar archivos por línea de comandos si existe tsconfig.json
- Si se ejecuta
tsc foo.tsy en el mismo directorio existetsconfig.json, se producirá un error - Puede ignorarse explícitamente con el flag
--ignoreConfig
Preparando TypeScript 7.0
- Las opciones desaprobadas en 6.0 pueden seguir usándose sin error con
"ignoreDeprecations": "6.0", pero en 7.0 se eliminarán por completo - La herramienta ts5to6 permite ajustar automáticamente cosas como
baseUrlyrootDir - El lanzamiento de TypeScript 7.0 está previsto dentro de unos meses, y ya se está adoptando ampliamente en grandes bases de código dentro y fuera de Microsoft
- Se recomienda enviar feedback mediante los builds nightly del preview nativo y la extensión de VS Code
3 comentarios
¡Tengo muchas ganas de que llegue el momento en que se haga la transición completa a un compilador basado en Go!
¿Eh? ¿TypeScript después va a cambiar a una versión nativa basada en Go?
Solo el compilador