---
title: "Instalé TypeScript 7 y ESLint dejó de arrancar: no hay versión que lo arregle"
excerpt: "TypeScript 7 typechequea 4 veces más rápido, pero no expone API JavaScript. Todo lo que lee tipos programáticamente se queda fuera, y el linter es lo primero que cae. Probé cinco mecanismos de pnpm para darle un TS 6 solo a ESLint: ninguno funciona, y el motivo enseña algo sobre cómo se resuelven los peers."
date: "2026-08-04T00:30:00.000Z"
category: "Next.js"
tech_article: true
author:
  name: "angel cruz"
  picture: "https://angelcruzdevcdn.nyc3.cdn.digitaloceanspaces.com/images/me/angel-cruz.png"
ogImage:
  url: "/images/open-graph/next-opengraph-image.png"
seo_title: "TypeScript 7 rompe ESLint: por qué y qué opciones quedan"
seo_description: "TypeScript 7 no expone API JavaScript, así que typescript-eslint aborta y ESLint no puede parsear .ts. Por qué ninguna versión lo arregla, los cinco intentos con pnpm que fallan y las dos salidas reales."
---

El typecheck bajó de 3,15 segundos a 0,69. El build de Next pasó de 3,3 segundos a 378 milisegundos typechequeando. Tres de mis cuatro gates de CI en verde y más rápidos que nunca.

El cuarto no arranca, y no hay nada que instalar para arreglarlo.

## Cómo llegué aquí

Next.js 16.3 salió recomendando TypeScript 7, que es el port nativo del compilador. Sus propios docs son escuetos sobre lo que hay que hacer:

> TypeScript 7 does not currently provide the JavaScript compiler API. To use TypeScript 7 during `next build`, install it in your project.

```bash
pnpm add -D typescript@^7
```

Eso es todo. Next usa el CLI local de `tsc` por defecto, así que no hay configuración extra. Lo instalé, corrí los gates y salió esto:

```
typecheck  ✓  0.69s
test       ✓  104 passed
build      ✓  TypeScript en 378ms
lint       ✗
```

## El error dice exactamente lo que pasa

```
typescript-eslint does not support TS 7.0.
Please see .../#running-side-by-side-with-typescript-6.0 to run
typescript-eslint using the TS 6 API.
See also .../issues/10940 for tracking typescript-eslint's
support for TS >=7.1
```

Fíjate en la frase de los docs de Next otra vez, porque es la causa entera: **no expone API JavaScript**. TypeScript 7 hoy existe solo como binario de línea de comandos.

Y un linter de TypeScript no puede trabajar con un binario. Necesita entrar al compilador por código: recorrer el AST, preguntar el tipo de una expresión, resolver un símbolo. Eso es la API JavaScript, y en la 7 todavía no está. La API estable programática está planificada para 7.1, no para 7.0.

Lo importante es que esto no afecta solo al linter. Afecta a todo lo que lee tipos programáticamente, y hay issues abiertos por el mismo motivo aguas arriba, como el de [ts-api-utils](https://github.com/typescript-eslint/ts-api-utils/issues/1051), la librería sobre la que typescript-eslint construye sus checks de tipos.

## No es un rango de peer desactualizado

Mi primera reacción fue la obvia: el peer estará mal puesto, instalo una versión nueva y listo. No.

```bash
$ npm view typescript-eslint@8.66.0 peerDependencies
{ "typescript": ">=4.8.4 <6.1.0" }

$ npm view typescript-eslint@8.66.1-alpha.0 peerDependencies
{ "typescript": ">=4.8.4 <6.1.0" }
```

Ni `latest` ni `canary` mueven ese tope. Y el rechazo no vive en el paquete que importas, vive en el core compartido. Lo comprobé cargando cada entrada por separado:

```bash
$ node -e "import('@typescript-eslint/parser')"
FAIL: typescript-eslint does not support TS 7.0.

$ node -e "import('@typescript-eslint/eslint-plugin')"
FAIL: typescript-eslint does not support TS 7.0.
```

El issue que pide soporte para 7.0.2 está **cerrado como *not planned***. El de adoptar el compilador nativo sigue abierto, bloqueado por algo que no depende de typescript-eslint: ESLint no soporta parsers asíncronos, y el compilador nativo se consume por binding nativo o WASM, que es asíncrono.

O sea que no hay fecha. No es "espera al martes".

## Los cinco intentos con pnpm

Si TypeScript 7 tiene que estar en la raíz y ESLint necesita un 6, la idea evidente es darle un 6 solo a ESLint. pnpm tiene mecanismos para eso. Probé todos y anoto por qué fallan, porque el patrón es el mismo y explica bastante.

**1. `packageExtensions` con `dependencies`.** Inyectar un `typescript` real dentro de cada paquete de typescript-eslint, apuntando al shim de la 6:

```yaml
packageExtensions:
  "@typescript-eslint/typescript-estree":
    dependencies:
      typescript: npm:@typescript/typescript6@^6.0.2
```

El symlink acabó apuntando a la 7 igual:

```bash
$ readlink node_modules/.pnpm/typescript-eslint@.../node_modules/typescript
../../typescript@7.0.2/node_modules/typescript
```

**2. `packageExtensions` con `peerDependencies`,** para corregir el rango declarado. Tampoco cambia la resolución.

**3. `overrides` por rango.** Este casi funciona, y su forma de fallar es la más instructiva:

```yaml
overrides:
  "typescript@>=4.8.4 <6.1.0": npm:@typescript/typescript6@^6.0.2
```

Alcanzó una instancia, pero no la que `eslint-config-next` empaqueta. Ese paquete declara `typescript: >=3.3.1`, un rango que acepta la 7, así que se llevaba el compilador de la raíz. Al añadir ese segundo rango al override desapareció TypeScript 7 del proyecto entero: **el selector matchea por versión resuelta, no por el string declarado**, y `7.0.2` satisface `>=3.3.1`. No hay forma de distinguir el peer laxo de la dependencia de la raíz.

**4. `overrides` con `padre>hijo`,** incluido el padre correcto:

```yaml
overrides:
  "eslint-config-next>typescript": npm:@typescript/typescript6@^6.0.2
```

Nada.

**5. Quitar `eslint-config-next` y declarar los seis plugins directos,** para que exista una sola copia de typescript-eslint y el override la alcance. Al ser dependencia directa de la raíz, su peer se resolvió a la 7 de la raíz. Peor punto de partida que el inicial.

La razón única detrás de los cinco: **los peer dependencies se resuelven desde quien importa, no desde quien los declara.** Los overrides y las packageExtensions actúan sobre dependencias normales. Un peer siempre acaba mirando al importador, y el importador aquí es la raíz, donde vive TypeScript 7. Ninguna capa de configuración de pnpm se interpone ahí.

## Las dos salidas que quedan

Ni una es bonita.

**La primera es el shim oficial.** Microsoft publica `@typescript/typescript6`, que reexporta la API de la 6, y documenta instalarlo lado a lado:

```json
{
  "devDependencies": {
    "@typescript/native": "npm:typescript@^7.0.2",
    "typescript": "npm:@typescript/typescript6@^6.0.2"
  }
}
```

El nombre `typescript` pasa a ser el shim, que es lo que ESLint necesita, y la 7 entra bajo otro nombre aportando el binario `tsc`. Funciona: los cuatro gates en verde, y la 7 sigue typechequeando todo.

El precio es que tu `package.json` deja de decir la verdad de un vistazo. Alguien que lo abra lee `typescript: @typescript/typescript6` y concluye que el proyecto está en la 6. Y en Next hay un detalle extra: su checker busca `bin.tsc` dentro del paquete `typescript`, y el shim expone `tsc6`, así que el build no arranca sin apagar el checker interno y encadenar `tsc --noEmit` en el script.

**La segunda es aceptar que no hay linter.** TypeScript 7 pelado, `package.json` honesto, y el gate de lint fuera hasta que upstream se ponga al día.

Elegí esta. El proyecto es un blog estático con typecheck estricto y 104 tests, y el typecheck es el que caza lo que de verdad rompe producción. Perder las reglas de `@typescript-eslint` durante unas semanas duele menos que dejar en el repo un `package.json` que miente sobre su propia versión de TypeScript. Lo dejé escrito en el workflow, porque un paso ausente sin explicación se lee como un olvido:

```yaml
# FALTA EL PASO DE LINT, y no es un olvido: el proyecto usa TypeScript 7,
# que todavía no expone API JavaScript (solo CLI). typescript-eslint
# depende de esa API, así que aborta al ver un 7.x y ESLint no puede ni
# parsear los .ts.
```

## Conclusión

La pregunta útil antes de subir a TypeScript 7 no es si tu código compila. Compila. Es **qué herramientas de tu stack leen tipos por código**, porque esas son las que se caen: linters, transformers de AST, cualquier cosa construida sobre la API del compilador.

Si tu respuesta es "solo `tsc`", sube hoy y disfruta los 4x. Si tienes un linter con reglas type-aware, y casi cualquier proyecto TypeScript serio lo tiene, la decisión no es técnica: es si prefieres un `package.json` raro o un gate de calidad menos, hasta que llegue la 7.1.

Que es, por cierto, un buen recordatorio de que "10 veces más rápido" nunca es el coste total de una migración.

Si quieres seguir el hilo: el [anuncio de TypeScript 7.0](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/), los docs de [Next sobre TypeScript](https://nextjs.org/docs/app/api-reference/config/typescript), y los issues [typescript-eslint#10940](https://github.com/typescript-eslint/typescript-eslint/issues/10940) y [#12518](https://github.com/typescript-eslint/typescript-eslint/issues/12518).

---

## Sitemap

Índice completo del sitio: [/sitemap.md](https://www.angelcruz.dev/sitemap.md)

Canónico HTML: [https://www.angelcruz.dev/post/typescript-7-sin-api-javascript-eslint](https://www.angelcruz.dev/post/typescript-7-sin-api-javascript-eslint)
