Se hai mai inviato una correzione di due righe a un monorepo TypeScript e hai visto la tua pipeline di build consumare dieci minuti di controllo dei tipi, comprendi già il problema. Il ritardo non è dovuto al bundling. Non è dovuto alla minificazione. È il momento in cui TypeScript cerca di scrivere i tuoi file di dichiarazione. Prima di poter emettere un singolo file .d.ts, il compilatore deve risolvere l'intero grafo dei tipi. Scansiona gli import, valuta i generici e inferisce i tipi di ritorno che potrebbero trovarsi tre livelli di dipendenza più in profondità. Quel singolo file che hai modificato tocca un altro file, che ne tocca un terzo, e improvvisamente il compilatore sta svolgendo un lavoro da detective su tutto il repository solo per descrivere cosa restituisce la tua funzione.

TypeScript 6.0 introduce isolatedDeclarations per rompere questa abitudine.

Il vero collo di bottiglia

I file di dichiarazione sono il contratto pubblico del tuo codice. Quando un altro sviluppatore importa il tuo pacchetto, TypeScript legge i file .d.ts, non il codice sorgente. Generare correttamente questi file significa che il compilatore non può saltare il controllo dei tipi. Deve conoscere ogni forma, ogni unione e ogni tipo di ritorno inferito prima di scrivere una singola riga di output.

In un piccolo progetto con cinquanta file, questo è istantaneo. In un grande monorepo con migliaia di moduli, è un incubo serializzato. Cambia un tipo di utilità in un pacchetto core e il compilatore rivisita ogni consumatore per verificare che i tipi inferiti siano ancora validi. Il tempo di build scala con la profondità delle dipendenze, non solo con il numero di file. Un refactoring banale può innescare una ricalcolazione dell'intero grafo. I team spesso accettano questo come inevitabile. Non lo è.

Come funziona isolatedDeclarations

Il nuovo flag cambia il contratto tra te e il compilatore. Invece di chiedere a TypeScript di inferire i tipi delle tue esportazioni, li annoti tu stesso. Questo singolo cambiamento elimina la necessità di una conoscenza globale. Il compilatore non deve più analizzare le tue dipendenze per emettere le dichiarazioni per il tuo modulo. Guarda solo la sintassi che ha davanti.

Ciò significa che ogni file può emettere il proprio output .d.ts in modo indipendente, in parallelo. Lo strumento di build non ha bisogno di costruire un grafo dei tipi completo prima di iniziare la generazione delle dichiarazioni. Strumenti come esbuild e swc, che in precedenza evitavano l'emissione di .d.ts perché privi di un controllo dei tipi, ora possono generare dichiarazioni a velocità quasi pari alla transpilazione. Leggono le annotazioni esplicite direttamente dal sorgente e scrivono le definizioni di tipo corrispondenti senza risolvere alcuna equazione di tipo.

In precedenza, l'emissione delle dichiarazioni era un monopolio di tsc perché solo il compilatore ufficiale possedeva le informazioni sui tipi necessarie per produrre i file .d.ts. I transpiler veloci potevano rimuovere i tipi o convertire la sintassi, ma non potevano generare definizioni di tipo. Con isolatedDeclarations, si apre la strada all'intero ecosistema per gestire i flussi di lavoro delle dichiarazioni. La trasformazione diventa meccanica piuttosto che logica. È proprio questa distinzione che trasforma un'attesa di dieci minuti in pochi secondi.

Il compromesso: l'esplicito è il nuovo default

La velocità ha un prezzo chiaro. Ogni funzione, classe e variabile esportata deve avere un'annotazione di tipo esplicita. TypeScript si rifiuterà di inferire l'API pubblica per te.

Considera una semplice utility:

export function getUser(id: number) {
  return fetchUser(id);
}

Con isolatedDeclarations abilitato, questo genererà un errore. Il compilatore non può conoscere il tipo di ritorno di fetchUser senza ispezionarlo, e con questo flag