Declaration Merging (scalanie deklaracji) to unikalny mechanizm TypeScript, który pozwala na łączenie deklaracji o tej samej nazwie w jeden typ/encji. Działa to dla interfejsów, przestrzeni nazw i funkcji.
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
Jak zachodzi scalanie metod o tej samej nazwie w różnych przestrzeniach interfejsu i co się stanie, jeśli ich sygnatury różnią się?
Odpowiedź:
Jeśli zadeklarujesz w różnych interfejsach scalających metody o tej samej nazwie, TypeScript spróbuje "przeciążyć" te metody w ostatecznym interfejsie. Jednak jeśli sygnatury są niekompatybilne (nie mogą być przeciążane), spowoduje to błąd kompilacji.
Przykład:
interface Foo { bar(a: number): void } interface Foo { bar(a: string): void } // OK: przeciążenia interface Foo { bar(a: number[]): void } // Błąd: niekompatybilne sygnatury
Historia
W jednym projekcie rozszerzano zewnętrzny interfejs Window przez scalanie deklaracji dla różnych funkcji: jedna drużyna dodała window.myFeature: boolean, a druga window.myFeature: number. Merge spowodował błąd typów, a kompilator wykrył konflikt dopiero podczas ogólnej kompilacji — ktoś musiał szybko zmienić nazwę.
Historia
Przez pomyłkę zadeklarowano dwa interfejsy ArrayHelper z różnymi sygnaturami metod, oczekując, że zestawią się w "oba warianty dostępne". W rzeczywistości pierwsza sygnatura przesłoniła drugą, co doprowadziło do nieprawidłowego autouzupełniania w IDE i błędu podczas integracji z nowym modułem.
Historia
Używając przestrzeni nazw do "rozszerzenia" funkcji przez scalanie deklaracji, programista błędnie zadeklarował export wewnątrz namespace, a funkcja okazała się niedostępna. Dopiero po przeglądzie stwierdzono, że bez prawidłowego exportu scalanie nie działa i właściwości nie pojawiają się w funkcji.