TypeScript: Enhance Variable Types with Declaration Merging
This story is about an often applied technique by libraries that offer full TypeScript support. Although as a consumer of these things…
TypeScript: Enhance Variable Types with Declaration Merging

This story is about an often applied technique by libraries that offer full TypeScript support. Although as a consumer of these things, one most often does not have to implement such techniques — everything just works like magic. Nevertheless, it is always good to have a basic understanding of what is going on in the hidden layer especially in times where things go wrong.
One of TypeScript’s features is the so called declaration merging (see here). Applied on an interface, this in principle is merging two declarations of the same interface:
interface TheInterface{
a: string;
}
interface TheInterface{
b: boolean;
}
let t: TheInterface = {
a: 'a',
b: true
};
Typically, when we use external libraries that come with their own type declarations it sometimes is necessary to extend a type with some custom fields.
For instance, let us consider a session store:
interface Session{}
As a consumer we want to store custom properties like authToken, socketId, ... in a user’s session but of course the library doesn’t cope for these fields.
We could use the as any trick and hence making the compiler allowing us to store any values on the session:
(session as any).authToken = ...
Obviously, this is not desirable since we loose compiler checks. Somebody could by accident write (session as any).authTypoToken = ... and no one would recognize this until a runtime error appears.
So, let us assume we are using some external library which types are imported like this:
import { Session } from 'path-to-extern-module'
In case Session is an interface we can enhance its type by adding the following to our source code:
declare module 'path-to-extern-module'{
interface Session{
authToken: string;
socketId: number;
}
}
Alternatively, and this is the cleaner approach, we can store this in a xxx.d.ts file (type declarations) and put it into our source folder.
Let us consider all this in more detail by looking at the following example:
Suppose we have a declaration file named some-module.d.ts:
export interface CustomTypes { };
export type Session =
CustomTypes extends {session: infer T} ? T : unknown;
export function fn(clb: (sess: Session) => void);
This intends to ‘simulate’ an external library. If you don’t know about the infer keyword you can find basic information here. The ternary in this code is like pattern matching. CustomTypes is checked to match a type that extends the type {session: infer T}. The infer T is just a placeholder for the type of session and assigns the latter to the generic T. People coming from logic programming will appreciate this pattern.
Having only this code, Session obviously would turn out to be the type unknown. But if someone, extends CustomTypes by using declaration merging, things can change:
In our source code we could import these types and use them like so:
import { Session, fn } from './some-module';
interface MySession {
authToken: string;
socketId: number;
}
declare module './some-module' {
interface CustomTypes {
session: MySession;
}
}
fn(sess => console.log(sess.authToken)); // compiles!
This way sess would have the type MySession, since the declaration of CustomerTypes has been merged.
If we would leave away the declaration merging, that is:
import { fn } from './some-module';
fn(sess => console.log(sess.authToken)); // error!
Then this resulted in a compilation error since the variable sess would be of type unknown.
Conclusion
There you have it, we’ve answered the age-old question of whether APIs and Microservices were the same things.
As it turns out, all we had to do was to carefully look at the definition of each one. In the end, they’re not the same, but they work incredibly well together.
What do you think? Do you still have questions? Leave them in the comments!
Build composable web applications
Don’t build web monoliths. Use Bit to create and compose decoupled software components — in your favorite frameworks like React or Node. Build scalable frontends and backends with a powerful and enjoyable dev experience.
Bring your team to Bit Cloud to host and collaborate on components together, and greatly speed up, scale, and standardize development as a team. Start with composable frontends like a Design System or Micro Frontends, or explore the composable backend. **Give it a try →**

Learn More
메타데이터
- post_id
- 9f0ce0af309d
- slug
- enhancing-the-type-of-a-variable-declaration-merging-9f0ce0af309d
- url
- https://medium.com/bitsrc/enhancing-the-type-of-a-variable-declaration-merging-9f0ce0af309d
- canonical_url
- https://medium.com/bitsrc/enhancing-the-type-of-a-variable-declaration-merging-9f0ce0af309d
- author_url
- https://medium.com/@applied-math-coding
- status
- ok
- fetched_at
- 2026-08-04 05:53:42