Declaration Merging (fusione di dichiarazioni) è un meccanismo unico di TypeScript che consente di combinare dichiarazioni con lo stesso nome in un unico tipo/soggetto. Questo funziona per interfacce, spazi dei nomi e funzioni.
interface User { name: string; } interface User { age: number; } const u: User = { name: 'Vasya', age: 42 }; // OK
function helper() {} namespace helper { export function extra() {} } helper.extra(); // OK
Come avviene la fusione di metodi con lo stesso nome in diversi spazi dell'interfaccia, e cosa succede se le loro firme sono diverse?
Risposta:
Se dichiari nei diversi merge-interfacce metodi con lo stesso nome, TypeScript cercherà di "overloadare" questi metodi nell'interfaccia finale. Tuttavia, se le firme non sono compatibili (non possono essere sovraccaricate), ciò porterà a un errore di compilazione.
Esempio:
interface Foo { bar(a: number): void } interface Foo { bar(a: string): void } // OK: sovraccarichi interface Foo { bar(a: number[]): void } // Errore: firme incompatibili
Storia
In un progetto hanno esteso l'interfaccia Window di terze parti tramite declaration merging per diverse funzionalità: un team ha aggiunto window.myFeature: boolean, un altro window.myFeature: number. La fusione ha causato un errore di tipi, e il compilatore ha rilevato il conflitto solo durante la raccolta generale – a qualcuno è toccato fare un rinomina in fretta.
Storia
Per errore hanno dichiarato due interfacce ArrayHelper con firme di metodi diverse, aspettandosi che si combinassero in "entrambi i varianti disponibili". In realtà, la prima firma ha sovrascritto la seconda, portando a un completamento automatico errato nell'IDE e a un bug durante l'integrazione con un nuovo modulo.
Storia
Utilizzando uno spazio dei nomi per "espandere" una funzione tramite declaration merging, lo sviluppatore ha dichiarato erroneamente l'export all'interno del namespace, e la funzione è risultata non disponibile. Solo dopo la revisione hanno scoperto che senza il corretto export la fusione non funziona e le proprietà non appaiono sulla funzione.