设计思路
- 定义一个基础的
RequestWithExtra
接口,用于包含所有可能扩展的属性类型。
- 在各个中间件中,通过类型断言将
req
对象转换为 RequestWithExtra
类型,从而安全地使用扩展属性。
- 将
RequestWithExtra
接口封装在一个单独的 TypeScript 模块中,方便在不同中间件文件中导入复用。
关键代码示例
- 创建类型扩展模块(
types/expressExtensions.ts
)
import { Request } from 'express';
// 定义包含所有扩展属性的接口
export interface RequestWithExtra extends Request {
userInfo?: { [key: string]: any };
tokenPayload?: { [key: string]: any };
}
- 在中间件中使用类型扩展
import { Request, Response, NextFunction } from 'express';
import { RequestWithExtra } from './types/expressExtensions';
// 示例中间件,添加 userInfo 到 req
export const addUserInfoMiddleware = (req: Request, res: Response, next: NextFunction) => {
const reqWithExtra = req as RequestWithExtra;
reqWithExtra.userInfo = { name: 'John Doe', age: 30 };
next();
};
// 示例中间件,添加 tokenPayload 到 req
export const addTokenPayloadMiddleware = (req: Request, res: Response, next: NextFunction) => {
const reqWithExtra = req as RequestWithExtra;
reqWithExtra.tokenPayload = { sub: '12345', exp: Date.now() + 3600 };
next();
};
- 在 Express 应用中使用中间件
import express from 'express';
import { addUserInfoMiddleware, addTokenPayloadMiddleware } from './middlewares';
import { RequestWithExtra } from './types/expressExtensions';
const app = express();
app.use(addUserInfoMiddleware);
app.use(addTokenPayloadMiddleware);
app.get('/', (req: RequestWithExtra, res) => {
console.log(req.userInfo);
console.log(req.tokenPayload);
res.send('Hello World!');
});
const port = 3000;
app.listen(port, () => {
console.log(`Server running on port ${port}`);
});