ProgrammatieTypescript ontwikkelaar

Vertel over het Mechanisme van Declaration Merging in TypeScript. Hoe werkt het voor interfaces, functies en namespaces, en wat zijn hier de valkuilen?

Slaag voor sollicitatiegesprekken met de Hintsage AI-assistent

Antwoord.

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.

  1. Interfaces: interfaces met dezelfde naam worden samengevoegd tot één grote interface:
interface User { name: string; } interface User { age: number; } const u: User = { name: 'Vasya', age: 42 }; // OK
  1. Functies + namespace: een functie en een namespace met dezelfde naam worden samengevoegd — statische methoden worden verzameld:
function helper() {} namespace helper { export function extra() {} } helper.extra(); // OK
  1. Namespace + enum en namespace + class: samenvoegen is ook mogelijk voor het uitbreiden van klassen en enums met statische eigenschappen.

Vraag met een valstrik.

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

Voorbeelden van echte fouten door onwetendheid over de subtiliteiten van het onderwerp


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.