Storia della questione:
TypeScript è progettato per aggiungere tipizzazione statica alle applicazioni JS esistenti. Si pone quindi la domanda: come tipizzare un'importazione se stiamo collegando un modulo esterno o un nostro stesso modulo scritto in JavaScript puro, dove i tipi non sono presenti? In questo caso TypeScript utilizza i cosiddetti declaration files (.d.ts) oppure deduce i tipi automaticamente (a volte in modo errato).
Problema:
Se durante l'importazione TypeScript non trova una descrizione di tipo adeguata, la variabile assume il tipo any, il che significa una totale perdita di sicurezza tipologica. Questo può portare a errori che il compilatore non rileverà, causando bug durante il runtime. Spesso gli sviluppatori dimenticano di dichiarare esplicitamente i tipi per le funzioni/gli oggetti importati.
Soluzione:
Esempio di codice:
// 1. Tipizzazione esplicita dell'importazione del modulo JS import myFunc from './myLib'; declare function myFunc(x: number): boolean; // 2. Importazione da un modulo JS per il quale è stato creato il file myLib.d.ts con export function myFunc(x: number): boolean; import { myFunc } from './myLib'; // 3. Importiamo un modulo senza tipizzazione e descriviamo esplicitamente il tipo import * as legacy from './legacy'; const typedLegacy: { runTask: (name: string) => void } = legacy;
Caratteristiche principali:
Può TypeScript dedurre automaticamente i tipi di un modulo JS importato senza dichiarazioni?
No, se il file è scritto in JavaScript, senza dichiarazioni di tipo TypeScript è costretto a presumere any e perde informazioni sui tipi, tranne per casi triviali (export const x = 1;).
È possibile "estendere" i tipi importati se nuovi campi appaiono nel modulo JS?
Solo se aggiorni il file di dichiarazione (.d.ts). Se i tipi sono fissati in .d.ts, TypeScript li userà come "verità", eventuali nuovi campi rimarranno senza tipizzazione o porteranno a un errore.
È sicuro importare un modulo JS esterno in un progetto TypeScript se non esistono @types/ e dichiarazioni?
No, questo diminuisce drasticamente la sicurezza: l'intero lavoro con l'importazione risulta untyped (any), il compilatore non genererà errori, anche se il modulo non è disponibile o l'API è cambiata. Lavorare con tali moduli è accettabile solo come soluzione temporanea, con tipizzazione esplicita o isolamento del codice.
Un sviluppatore importa una libreria JS esterna senza dichiarazioni, utilizzando l'API con sicurezza, ottenendo il tipo any. Dopo l'aggiornamento della libreria, la firma dei metodi cambia, ma non si verificano errori, solo bug durante il runtime.
Vantaggi:
Svantaggi:
Si crea un file di dichiarazione .d.ts o si aggiunge un pacchetto @types/, la descrizione dell'API corrisponde esattamente al modulo JS sorgente. Tutti i metodi importati sono tipizzati, l'IDE offre suggerimenti di completamento automatico, eventuali discrepanze mostrano un errore di compilazione.
Vantaggi:
Svantaggi: