# Astro check non funziona con TypeScript 7: meglio correggere le dipendenze che togliere il controllo dei tipi

> Canonical: https://vxi.me/it/posts/astro-check-typescript-7-compatibility/
> Locale: it-it
> Published: 2026-10-11
> Updated: 2026-10-11
> Markdown: https://vxi.me/it/posts/astro-check-typescript-7-compatibility.md

Una pull request di Dependabot ha aggiornato TypeScript dalla versione 6.0.3 alla 7.0.2. A guardare soltanto i numeri sembra un normale aggiornamento major. In un progetto Astro, però, può essere sufficiente a far smettere di funzionare `astro check`.

Esaminando [una issue pubblica di un progetto Astro/Starlight](https://github.com/sivadotblog/vishwakarma/issues/8), ho trovato due possibili rimedi molto diversi. Il primo eliminava `astro check` dalla CI, così il controllo che falliva non veniva più eseguito. Il secondo riportava TypeScript alla serie 6, conservava il checker e impediva temporaneamente a Dependabot di proporre ancora aggiornamenti alla 7.x. **È stata integrata la seconda soluzione.**

Non era soltanto una dichiarazione di peer dependency rimasta indietro. TypeScript 7.0 ha adottato un compilatore nativo e alcuni strumenti per i framework dipendono ancora dall'API programmatica di TypeScript 6. Nell'[annuncio ufficiale di TypeScript 7.0](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/), Microsoft consiglia esplicitamente di mantenere TypeScript 6 per le integrazioni con linguaggi incorporati, come Astro, Vue, Svelte e MDX, finché gli strumenti non avranno completato la migrazione.

Una precisazione sulle prove: ho letto le dipendenze a un commit preciso, le due PR e il run GitHub Actions del progetto originale. Ho anche eseguito personalmente cinque test sintetici con la sola libreria standard di Node.js, per capire come `exports` possa far sembrare assente un pacchetto già presente. **Non ho eseguito `npm install` né `astro check` nel progetto Astro interessato.** La CI riuscita di cui parlerò è un risultato del progetto originale, non una riproduzione indipendente fatta da me.

## Due soluzioni: eliminare il controllo o ripristinare una versione compatibile

Il caso è documentato in [vishwakarma Issue #8](https://github.com/sivadotblog/vishwakarma/issues/8). In precedenza [Dependabot PR #3](https://github.com/sivadotblog/vishwakarma/pull/3) aveva aggiornato TypeScript alla 7.0.2. Il maintainer ha segnalato che con quella combinazione `astro check` incontrava problemi di compatibilità.

[PR #9](https://github.com/sivadotblog/vishwakarma/pull/9) proponeva di togliere il checker. La modifica rimuoveva lo script `check` e la dipendenza `@astrojs/check` da `apps/web/package.json`, eliminando anche `typecheck-web` dal Makefile. `check-web` sarebbe così rimasto limitato alla formattazione e alla build. La PR è stata chiusa **senza merge**.

Se smetti di eseguire il controllo che fallisce, è possibile che la CI torni verde. Ma una `astro build` riuscita non equivale ai controlli sui tipi che `astro check` esegue sui file `.astro` e sul codice TypeScript. In quel caso non hai risolto il problema: hai rinunciato a una verifica che prima proteggeva il progetto.

La [PR #10](https://github.com/sivadotblog/vishwakarma/pull/10), quella effettivamente integrata, ha mantenuto il checker e ripristinato la dipendenza TypeScript del workspace web:

```diff
- "typescript": "^7.0.2"
+ "typescript": "^6.0.3"
```

Nel [commit pubblico fissato dopo la correzione](https://github.com/sivadotblog/vishwakarma/tree/9837d456647d948207941c86244e253594aef9ae), `apps/web/package.json` indica Astro `^7.2.10` e `@astrojs/check` `^0.9.10`. Lo stesso [`package-lock.json`](https://github.com/sivadotblog/vishwakarma/blob/9837d456647d948207941c86244e253594aef9ae/package-lock.json) blocca `@astrojs/check@0.9.10` e dichiara questo intervallo per TypeScript:

```json
"peerDependencies": {
  "typescript": "^5.0.0 || ^6.0.0"
}
```

È una **dichiarazione letta dal lockfile**, non il messaggio di un comando npm che ho eseguito personalmente. Almeno per questa versione del checker, TypeScript 7 non rientra nell'intervallo peer supportato.

Esiste anche una prova esterna dell'esecuzione dopo il fix. [GitHub Actions #38103905437](https://github.com/sivadotblog/vishwakarma/actions/runs/38103905437) ha girato sull'head della PR `5d828e8d55c5db833f5cca17f28da3b6aba05a99`. Il job web, compresi `make setup-web` e `make check-web`, e il job Python sono terminati con successo. È una conferma dello **stato corretto con il checker ancora presente**. Non dimostra che io abbia riprodotto indipendentemente il guasto con TypeScript 7.

## Come può risultare mancante un TypeScript che è già installato?

Ci sono due livelli di incompatibilità da distinguere.

Il primo è più profondo e riguarda le API del compilatore. [TypeScript 7.0](https://devblogs.microsoft.com/typescript/announcing-typescript-7-0/) è passato a un'implementazione nativa in Go. Il fatto che `tsc` funzioni come comando non significa che l'API programmatica stabile di TypeScript 6 sia rimasta disponibile. Astro deve analizzare TypeScript *dentro* i file `.astro` attraverso i propri servizi di linguaggio. Aggiornare il compilatore da riga di comando non completa automaticamente quell'integrazione.

Il secondo livello rischia di mandare fuori strada durante il debug. Nell'[Issue #17268 di Astro](https://github.com/withastro/astro/issues/17268) è documentato come il cambiamento degli `exports` di TypeScript 7 possa far fallire una vecchia verifica basata su `require.resolve('typescript')` con `ERR_PACKAGE_PATH_NOT_EXPORTED`. Se il programma interpreta qualsiasi errore di risoluzione come «TypeScript non installato», mostra un suggerimento inesatto.

Ho voluto verificare soltanto questo meccanismo, senza installare tutto Astro o il vero TypeScript 7. Con la libreria standard di Node.js v22.16.0 ho creato due **pacchetti simulati e temporanei**: uno con il classico punto d'ingresso e uno che esporta solo `./package.json`, senza esportare la radice del pacchetto. Ecco la parte importante della configurazione usata realmente, leggermente riordinata:

```js
{
  name: 'native-ts-synthetic',
  version: '7.0.0-fixture',
  type: 'module',
  exports: {
    './package.json': './package.json'
  }
}
```

Per questo **pacchetto sintetico**, `require.resolve('native-ts-synthetic')` produce `ERR_PACKAGE_PATH_NOT_EXPORTED` anche se i file sono presenti. Poiché il mock esporta esplicitamente `./package.json`, la risoluzione di `native-ts-synthetic/package.json` funziona e permette di riconoscere il pacchetto installato. Un pacchetto davvero inesistente restituisce `MODULE_NOT_FOUND` in entrambi i casi.

Ho eseguito `node --test ./node-exports-resolution.test.cjs` in un ambiente Linux isolato con Node.js v22.16.0, senza dipendenze npm di terze parti. Questo è un estratto del **vero output TAP di Node.js**, non un log di errore di Astro inventato:

```text
# OBSERVED: legacy package resolution = FOUND
# OBSERVED: package exists; require.resolve(root) = ERR_PACKAGE_PATH_NOT_EXPORTED
# OBSERVED: require.resolve(package.json) = FOUND
# OBSERVED: absent package = MODULE_NOT_FOUND in both paths
# OBSERVED: catch-all = false missing; code-aware fallback = detected installed
# tests 5
# pass 5
# fail 0
```

I cinque test sono passati, ma dimostrano **uno specifico comportamento della risoluzione dei pacchetti in Node.js**, non la compatibilità reale tra TypeScript 7, Astro e `astro check`. Nemmeno il fallback a `package.json` è universale: se un pacchetto non esporta quel percorso, anche questa ricerca può fallire.

Inoltre, sistemare l'individuazione dei pacchetti installati non ripristina l'API precedente assente in TypeScript 7.0. La [PR #18053 di Astro](https://github.com/withastro/astro/pull/18053), integrata a settembre 2026, ha migliorato i messaggi per gli errori con TypeScript 7. La chiusura della relativa issue **non prova il supporto completo alla versione 7.0**.

## Come recuperare la CI in un progetto Astro interessato

Con una combinazione simile di versioni, partirei controllando le versioni effettive di TypeScript e `@astrojs/check`, l'intervallo peer nel lockfile e l'errore originale. Una proposta di upgrade da Dependabot non garantisce che tutti gli strumenti del framework siano già pronti.

Nel repository dell'esempio esiste un workspace npm chiamato `web` sotto `apps/web`. Questi comandi sono **passi che un lettore può eseguire nel proprio branch di riparazione**, ricavati dalla [PR #10 pubblica](https://github.com/sivadotblog/vishwakarma/pull/10). Io non li ho eseguiti nel repository originale:

```bash
# Controllare le dipendenze in uso
npm ls typescript @astrojs/check -w web

# Ripristinare la versione compatibile scelta in questo caso
npm install --save-dev 'typescript@^6.0.3' -w web

# Reinstallare dal lockfile e verificare check e build
npm ci
npm run check -w web
npm run build -w web
```

Se esiste già un conflitto di dipendenze, `npm ls` può terminare con un codice diverso da zero: è un indizio utile. Prima conserva il commit iniziale o lavora su un branch separato e controlla le versioni richieste di Node/npm e il nome del workspace. In un progetto con un singolo pacchetto, `-w web` non serve. `^6.0.3` è **la soluzione di questo caso fissato**, non una prescrizione permanente per qualunque progetto Astro.

Poi eviterei che la stessa PR di aggiornamento major riaprisse il problema. Nel [`.github/dependabot.yml`](https://github.com/sivadotblog/vishwakarma/blob/9837d456647d948207941c86244e253594aef9ae/.github/dependabot.yml) del commit fissato compare questa regola temporanea relativa a npm:

```yaml
- package-ecosystem: npm
  directory: /
  schedule:
    interval: weekly
  ignore:
    - dependency-name: typescript
      versions: [">=7.0.0"]
```

L'`ignore` va inserito nell'ecosistema **npm** corretto, senza bloccare anche gli aggiornamenti delle altre dipendenze. È opportuno annotare quando eliminarlo: quando il checker e gli strumenti di linguaggio di Astro supporteranno davvero il nuovo sistema, e quando **la CI del proprio progetto** lo avrà verificato. Altrimenti una soluzione provvisoria rischia di diventare un blocco delle versioni senza scadenza.

Nel progetto esaminato `check-web` comprende formattazione, `astro check` e build. Per verificare una correzione serve quindi controllare separatamente che il lockfile contenga le versioni previste, che `npm ci` riproduca l'installazione, che `astro check` venga davvero eseguito e che la build continui a riuscire. Se c'è già un test che introduce un errore di tipo in un file `.astro`, sarebbe ancora meglio controllare che il checker sappia rilevarlo.

## TypeScript 7.1 permetterà di togliere subito il blocco?

Tornare temporaneamente a TypeScript 6 non significa rinunciare per sempre al nuovo compilatore. Nell'annuncio di TypeScript 7.0, Microsoft ha parlato del lavoro in corso su nuove API programmatiche e di opzioni come `@typescript/typescript6`, utili per far convivere strumenti più vecchi e il nuovo `tsc`. Tuttavia, il compilatore CLI, l'analisi dei template Astro, i servizi di linguaggio dell'editor e il controllo dei tipi in CI richiedono verifiche diverse.

Al momento della ricerca, l'[Issue #17268 di Astro](https://github.com/withastro/astro/issues/17268) era chiusa e la [PR #18053](https://github.com/withastro/astro/pull/18053) con messaggi di errore più chiari era stata integrata. Restava aperta la [PR #17852](https://github.com/withastro/astro/pull/17852), relativa al Content Mapper di TypeScript 7 per `.astro`. È lo stato delle fonti in quel momento, non una garanzia su ciò che i prossimi rilasci supporteranno.

Se un upgrade major rompe `astro check`, la sequenza ragionevole è controllare l'errore e il contratto delle dipendenze, **mantenere il checker**, ripristinare una combinazione compatibile e verificare lockfile e CI. La migrazione successiva può essere pianificata come attività separata. L'obiettivo è recuperare un controllo efficace, non soltanto zittire una pipeline rossa.

Per spiegare perché avevo scelto Astro per un blog tecnico, avevo scritto una precedente [analisi di Astro, Markdown e GitHub Actions](https://aitokenhacks.com/posts/astro-vs-wordpress-markdown-github-actions-blog/). Qui il problema arriva *dopo* quella scelta: evitare che un aggiornamento automatico delle dipendenze rimuova senza accorgersene uno dei controlli di qualità già presenti.
