Senior LevelExpress JS
How do you configure strict TypeScript declaration merging to extend Express Request (req.user, req.session)?
❓ Interview Prompt: Explain TypeScript declaration merging, module augmentation for Express.Request, and typing async route controllers safely.
When using TypeScript with Express, custom middleware frequently attaches data to the request object ('req.user = jwtPayload'). By default, TypeScript throws a compile error: 'Property "user" does not exist on type "Request"'.
How to Solve This via Declaration Merging:
Use Module Augmentation / Declaration Merging to globally extend the 'Express.Request' interface inside a custom '.d.ts' file:
1
Create 'src/types/express.d.ts'.
2
Include an 'export {}' statement to make the file a TypeScript module.
3
Declare global augmentation: 'declare global { namespace Express { interface Request { user?: UserDTO } } }'.
Code Implementation Example
typescript
// src/types/express.d.ts — TypeScript Module Augmentation
import { UserDTO } from '../dto/user.dto';
export {}; // Make this file a module!
declare global {
namespace Express {
interface Request {
user?: UserDTO;
tenantId?: string;
}
}
}
// src/controllers/userController.ts — req.user is now 100% type-safe!
import { Request, Response } from 'express';
export const getProfile = (req: Request, res: Response) => {
if (!req.user) return res.status(401).json({ error: 'Unauthorized' });
res.json({ id: req.user.userId, role: req.user.role });
};💡Extending Express.Request with global TypeScript declaration merging.
🎯 Interview Key Takeaway
Use declare global { namespace Express { interface Request { ... } } } in a .d.ts module file to add type safety for custom req properties.
#TypeScript#Declaration Merging#Type Safety#Senior
Back to all Express JS Questions→