Declaration Merging (samenvoegen van declaraties) is een uniek mechanisme van TypeScript dat het mogelijk maakt om declaraties met dezelfde naam samen te voegen tot één type/entiteit. Dit werkt voor interfaces, namespaces en functies.
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
Hoe gebeurt het samenvoegen van methoden met dezelfde namen in verschillende ruimtes van een interface, en wat gebeurt er als hun handtekeningen verschillen?
Antwoord:
Als je in verschillende samengevoegde interfaces methoden met dezelfde naam declareert, probeert TypeScript deze methoden te "overladen" in de uiteindelijke interface. Echter, als de handtekeningen niet compatibel zijn (niet kunnen worden overbelast), leidt dit tot een compilatiefout.
Voorbeeld:
interface Foo { bar(a: number): void } interface Foo { bar(a: string): void } // OK: overloads interface Foo { bar(a: number[]): void } // Fout: incompatibele handtekeningen
Verhaal
In een project breidden we een externe interface Window uit via declaration merging voor verschillende functies: één team voegde window.myFeature: boolean toe, een ander team window.myFeature: number. De merge veroorzaakte typefouten, en de compiler ontdekte het conflict alleen tijdens de gezamenlijke build — iemand moest snel een hernoeming doen.
Verhaal
Per ongeluk werden er twee interfaces ArrayHelper gedeclareerd met verschillende handtekeningen van methoden, in de veronderstelling dat ze zouden samenvoegen tot "beide varianten beschikbaar". In werkelijkheid overschreven de eerste handtekening de tweede, wat leidde tot onjuiste autocompletie in de IDE en een bug tijdens de integratie met de nieuwe module.
Verhaal
Door gebruik te maken van een namespace voor het "uitbreiden" van een functie via declaration merging, verklaarde de ontwikkelaar per ongeluk de export binnen de namespace verkeerd, en de functie bleek niet toegankelijk. Pas na de review bleek dat zonder de juiste export de merge niet werkt en eigenschappen niet op de functie verschijnen.