ProgrammazioneSviluppatore Frontend

Cosa sono i file di dichiarazione in TypeScript, quando e perché scrivere i propri file .d.ts? Come strutturare la descrizione dei tipi utente per i moduli JS esterni?

Supera i colloqui con l'assistente IA Hintsage

Risposta.

Storia della questione:

Molte librerie dell'ecosistema JavaScript forniscono solo file js sorgenti, senza avere propri tipi. Per descrivere i tipi di librerie di terze parti o personalizzate, nonché variabili globali, TypeScript implementa un formato speciale di file con estensione .d.ts (file di dichiarazione). Sono diventati uno standard per garantire informazioni sui tipi e sicurezza dei tipi in progetti sopra qualsiasi modulo js.

Problema:

Se i tipi per i moduli JS di terze parti non sono definiti, TypeScript è costretto a interpretare tali importazioni come any, e quindi si perdono tutti i vantaggi della tipizzazione statica: errori nelle chiamate, nei campi non esistenti, nei parametri sbagliati passano logicamente la compilazione e vengono identificati solo dopo l'esecuzione del codice. Inoltre, non è possibile effettuare completamento automatico e navigazione tra i tipi.

Soluzione:

Con i file di dichiarazione, è possibile descrivere manualmente i tipi per qualsiasi codice JS: funzioni, classi, oggetti, spazi dei nomi e persino costanti globali. In questo modo, il progetto rimane sicuro dal punto di vista dei tipi indipendentemente dall'origine della libreria esterna.

Esempio di codice:

// hello.d.ts declare module 'hello' { export function sayHello(name: string): string; } // app.ts import { sayHello } from 'hello'; sayHello('TypeScript'); // Tipo sicuro

Caratteristiche chiave:

  • Separano la descrizione delle firme e delle strutture dei tipi dall'implementazione (codice JS sorgente);
  • Permettono di implementare una rigorosa tipizzazione anche in build di terze parti/obsolete;
  • Nei file .d.ts è vietata l'implementazione, solo firme/descrizione.

Domande trabocchetto.

È possibile dichiarare l'implementazione delle funzioni direttamente nel file di dichiarazione?

No, nei file di dichiarazione è consentita solo la dichiarazione di strutture e firme, non la loro implementazione. Qualsiasi corpo di funzioni o costruttori causerà un errore di compilazione.

// Non è permesso: declare function sum(a: number, b: number) { return a + b; }

Dove cercare i tipi per i moduli npm popolari, se non sono presenti nel pacchetto sorgente?

Nel repository DefinitelyTyped (pacchetto npm @types/<lib>): quasi tutti i pacchetti popolari hanno tipizzazioni aggiornate sotto forma di moduli npm separati.

È possibile descrivere variabili globali (non tramite import) utilizzando un file .d.ts?

Sì, tramite il meccanismo delle dichiarazioni ambientali, ad esempio, declare var VERSION: string;. Questo è conveniente per descrivere window.X, costanti e variabili globali.

Errori tipici e anti-pattern

  • Scrivere corpi di funzioni e classi nei file .d.ts;
  • Descrivere firme incomplete o obsolete, causando conflitti con la struttura reale;
  • Collegare diversi tipi per un modulo/variabile globale, causando conflitti di tipo.

Esempi dalla vita

** Caso negativo Nel progetto viene utilizzata una libreria JS senza tipi. Gli sviluppatori si sono dimenticati del file .d.ts e accedono all'API tramite any. Si verificano bug durante l'aggiornamento della libreria: le chiamate obsolete si rompono, ma il compilatore non lo nota.

Vantaggi:

  • Avvio rapido, nessuna descrizione aggiuntiva necessaria.

Svantaggi:

  • Errori nascosti, comportamento non intenzionale, debug complesso su ampie quantità di codice.

** Caso positivo È stato sviluppato un file .d.ts proprio per l'attuale libreria, le firme sono mantenute aggiornate, si utilizza il completamento automatico e la navigazione IDE.

Vantaggi:

  • Completa sicurezza dei tipi, gli errori sono immediatamente visibili quando si modifica l'API;
  • Accelera lo sviluppo, è possibile integrare nuovi sviluppatori senza una profonda conoscenza del codice JS.

Svantaggi:

  • Supporto separato per i file .d.ts, è necessario monitorare la sincronizzazione durante gli aggiornamenti delle librerie JS.