Lesson 22 of 80
Two interfaces with the same name aren't a conflict — TypeScript combines them into one. A quirky-sounding rule that turns out to be exactly how you safely extend a third-party library's types.
12 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 2
You declare `interface User { name: string }` and later, elsewhere, `interface User { age: number }`. What happens?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
interface User { name: string }
interface User { age: number }
const u: User = { name: "Ada", age: 36 }; // has both — the two declarations merged
Two interface declarations with the same name merge into one interface with all their combined members, instead of the second one conflicting with (or overwriting) the first. This is a deliberate, useful feature — and it's exactly why the interfaces-vs-types lesson's "interfaces can be merged, type aliases can't" distinction matters in practice, not just as trivia.
// your app's types file
declare global {
namespace Express {
interface Request {
user?: { id: string }; // adds a `user` property to Express's Request type
}
}
}
Express's own Request interface didn't originally have a user field — auth middleware adds one at runtime, but the type needs to know about it too. Declaration merging lets you augment a library's existing types from your own code, without forking the library or editing its source — the two declarations (theirs and yours) merge into one, and every file that imports Request sees the combined shape.
interface Window { myGlobal: string; } — declared once, here.
.d.ts file with matching interface names to add or correct what the library ships.function declaration and a namespace with the same name combine so the namespace's exports become properties on the function.user is fine; redeclaring an existing property with an incompatible type is a real conflict TypeScript will flag."How would you add a custom property to Express's Request type without forking the library?" is a genuinely common real-world TypeScript problem, and declaration merging via module augmentation is the concrete, correct answer.