MST

星途 面试题库

面试题:TypeScript 下 Express 中间件类型扩展的模块封装与复用

你正在开发一个基于 Express 的大型项目,有多个中间件需要对 `req` 对象进行类似的类型扩展,例如添加 `userInfo`、`tokenPayload` 等属性。请设计一个 TypeScript 模块,将这些类型扩展进行封装,使其易于在不同的中间件文件中复用,并且要保证类型一致性和代码的简洁性。阐述设计思路并给出关键代码示例。
39.4万 热度难度
前端开发TypeScript

知识考点

AI 面试

面试题答案

一键面试

设计思路

  1. 定义一个基础的 RequestWithExtra 接口,用于包含所有可能扩展的属性类型。
  2. 在各个中间件中,通过类型断言将 req 对象转换为 RequestWithExtra 类型,从而安全地使用扩展属性。
  3. RequestWithExtra 接口封装在一个单独的 TypeScript 模块中,方便在不同中间件文件中导入复用。

关键代码示例

  1. 创建类型扩展模块(types/expressExtensions.ts
import { Request } from 'express';

// 定义包含所有扩展属性的接口
export interface RequestWithExtra extends Request {
    userInfo?: { [key: string]: any };
    tokenPayload?: { [key: string]: any };
}
  1. 在中间件中使用类型扩展
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();
};
  1. 在 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}`);
});