Skip to the solution
HardFrontend11 min read

What is module augmentation?

461 views

The problem

Question presented to candidate: "Your auth middleware puts a user on every request object, but the framework's Request type does not have it. How do you add that property to a third-party library's types without forking them, and what can go wrong?"

What a strong answer should cover:

  • Module augmentation: declare module "lib" { interface Request { user?: User } } inside a file that is itself a module merges new members into the library's exported interface
  • It is declaration merging across a module boundary, so you can extend interfaces (and namespaces), not type aliases; libraries expose interfaces like Vue's ComponentCustomProperties precisely to be augmented
  • The file must be a module (a top-level import/export): in a script file the same block is an ambient module declaration that replaces the library's types
  • Global augmentation: declare global { interface Window { ... } interface Array<T> { ... } } from a module, the same mechanism for global types
  • Augmentation is type-only: it never adds the run-time value, so the middleware, plugin or polyfill must really provide it; export default x inside an augmentation is TS2666
  • Placement: the augmenting file must be part of the compilation (include, or imported), otherwise the extra members silently disappear

Clarifying questions expected:

  • Is the property set on every request, or only after a specific middleware (should it be optional)?
  • Is this app code, or a library/plugin that should ship the augmentation to its users?

Code / implementation expected: Yes β€” a declare module block that adds a property to a library interface, and a usage that type-checks.

  • module-augmentation

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

11 min read Β· 11 sections

Run the code

Edit the code and run it here. Each console line with an expected value becomes a test.

TypeScriptGlobal augmentation: Array, Window and SymbolConstructor
TypeScriptAn augmentable event map, the pattern libraries use

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 75 of 81 in TypeScript

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

Up nextHard

What are recursive types?

Continue