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
ComponentCustomPropertiesprecisely 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 xinside 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.