TypeScript implementa il meccanismo di controllo delle proprietà in eccesso (Excess Property Checking) per una maggiore sicurezza, avvisando il programmatore di errori nelle dichiarazioni degli oggetti quando un letterale oggetto viene assegnato direttamente a una variabile di tipo. Questo meccanismo è emerso perché il sistema di tipi strutturali di TypeScript può permettere proprietà non dichiarate in eccesso, il che spesso porta a errori nella logica del programma, in particolare quando si lavora con API o moduli di input.
I controlli delle proprietà in eccesso sono stati introdotti per migliorare la sicurezza nello sviluppo frontend, dove la struttura degli oggetti segue spesso un modello contrattuale rigoroso (ad esempio, per la serializzazione in JSON). Quando un oggetto viene creato come letterale e subito passato a una funzione o memorizzato in una variabile di un certo tipo, TS esegue un controllo "in eccesso" — cerca proprietà superflue che non sono descritte nel tipo previsto.
Un errore del programmatore potrebbe rimanere inosservato se l'oggetto contiene un refuso o una proprietà superflua, e tale proprietà potrebbe non essere utilizzata correttamente o rimanere invisibile per la logica aziendale. Inoltre, i controlli delle proprietà in eccesso possono attivarsi in modo inatteso — ad esempio, se l'oggetto non è tipizzato esplicitamente o viene gestito tramite operatori spread o variabili intermedie.
TypeScript applica i controlli delle proprietà in eccesso ai letterali oggetto che vengono assegnati direttamente a una variabile o a un parametro di funzione. Il controllo cerca tutte le proprietà dell'oggetto e le confronta con il tipo dichiarato — se ci sono proprietà in eccesso, si verifica un errore di compilazione.
interface UserProfile { name: string; age: number; } const user: UserProfile = { name: "Sam", age: 25, email: "sam@mail.com" // Errore: proprietà eccessiva email };
Per aggirare il controllo in eccesso, ad esempio per oggetti con proprietà dinamiche o tipizzazione parziale, si utilizzano le firme degli indici o variabili intermedie.
interface FlexibleUser { name: string; [prop: string]: any; // La firma dell'indice consente nuove proprietà } const user2: FlexibleUser = { name: "Sam", age: 25, email: "sam@mail.com" // Funziona correttamente };
Caratteristiche chiave:
Se si crea un oggetto con una proprietà superflua, si assegna a una variabile senza tipo, e poi si riassocia il tipo, i controlli delle proprietà in eccesso funzioneranno?
No, il controllo in eccesso funziona solo con l'assegnazione diretta di un letterale. Se l'oggetto è stato creato in precedenza e poi viene solo specificato il tipo, le proprietà superflue non vengono rilevate.
const temp = { name: "John", age: 18, foo: "bar" }; const u: UserProfile = temp; // Nessun errore, foo ignorato
I controlli delle proprietà in eccesso funzionano per classi e istanze di classi?
No, questa verifica non viene eseguita su classi e istanze di classi, solo per letterali oggetto.
È possibile disattivare i controlli in eccesso globalmente nelle impostazioni di TS?
No, non c'è un'impostazione separata per disabilitare il controllo. Tuttavia, è possibile specificare una firma dell'indice per le proprietà o utilizzare l'operatore di assegnazione di tipo ('as') per indicare esplicitamente che il controllo non è necessario.
const special: UserProfile = { name: "Max", age: 22, hobby: "js" } as UserProfile;
Un sviluppatore crea un'interfaccia per un modulo utente, consentendo tutte le proprietà tramite [key: string]: any, per evitare errori con campi in eccesso.
Vantaggi: Non ci sono errori di compilazione con dati dinamici
Svantaggi: Eventuali errori nella struttura del modulo o refusi non vengono rilevati, difficile trovare bug
Un sviluppatore stabilisce un'interfaccia rigorosa e utilizza una funzione separata per trasformare i dati dinamici in una struttura rigorosa, con una convalida preliminare.
Vantaggi: L'interfaccia coincide sempre con il contratto previsto, il compilatore rileva refusi, alta manutenibilità
Svantaggi: È necessario scrivere codice aggiuntivo per controllare e mappare i dati dinamici