Declaration merging in TypeScript happens because the compiler treats certain kinds of code with the same name as parts of the same thing. Interfaces, namespaces, and a few other structures can be declared more than once, and the compiler merges them into a single definition. This lets you patch or extend types without rewriting what came before. It’s common in libraries, plugin systems, and situations where code needs to be flexible. But it only works in specific cases, and merging the wrong things or mixing sensitive data too freely can create bugs or security gaps.
How Declaration Merging Works Behind the Scenes
The compiler doesn’t always treat repeated declarations as conflicts. In some cases, it actively combines them. This only happens when certain types of declarations share the same name and are in a compatible scope. Interfaces and namespaces are the two main places where this merging takes effect, and each one has its own pattern. The compiler looks at the structure and combines them into a single definition that reflects all of the parts added across the declarations. The order just decides which overload gets picked first. It doesn’t affect how regular fields are merged.
Interfaces That Stack Up
Interfaces are one of the safest places where merging happens. When two or more interface declarations with the same name appear in the same scope, the compiler adds them together. You don’t need to import or wrap them in anything special. The compiler builds one interface out of all the matching pieces and uses that combined shape to type-check values.
Keep reading with a 7-day free trial
Subscribe to Alexander Obregon's Substack to keep reading this post and get 7 days of free access to the full post archives.