如何在NestJS拦截器构造函数传入参数,实现通用可配置化?
通用字符串转数字拦截器改造方案
你可以通过以下方式将拦截器改造为支持动态传入目标字段的通用版本:
改造后的拦截器代码
import { Injectable, NestInterceptor, ExecutionContext, CallHandler } from '@nestjs/common'; import { Observable } from 'rxjs'; import { map } from 'rxjs/operators'; @Injectable() export class EnumStringToNumberInterceptor implements NestInterceptor { // 构造函数接收目标字段名 constructor(private readonly targetKey: string) {} intercept(context: ExecutionContext, next: CallHandler): Observable<any> { return next.handle().pipe( map((data) => { // 处理列表结构数据 if (data?.list) { data.list.forEach((item) => { if (item[this.targetKey] !== undefined) { item[this.targetKey] = Number(item[this.targetKey]); } }); } // 处理单个对象数据 else if (data?.[this.targetKey] !== undefined) { data[this.targetKey] = Number(data[this.targetKey]); } return data; }), ); } }
使用示例
在控制器方法中直接传入需要转换的字段名即可:
import { Controller, Get, UseInterceptors } from '@nestjs/common'; import { EnumStringToNumberInterceptor } from './interceptors/enum-string-to-number.interceptor'; @Controller('games') export class GamesController { // 转换列表中的gameLevel字段 @Get() @UseInterceptors(new EnumStringToNumberInterceptor('gameLevel')) async getGameList() { // 返回包含list字段的响应数据 } // 转换单个对象中的userLevel字段 @Get(':id') @UseInterceptors(new EnumStringToNumberInterceptor('userLevel')) async getGameDetail(@Param('id') id: string) { // 返回单个对象格式的响应数据 } }
可选扩展优化
如果需要支持同时转换多个字段,可以修改构造函数接收字段数组,并批量处理:
@Injectable() export class EnumStringToNumberInterceptor implements NestInterceptor { constructor(private readonly targetKeys: string[]) {} intercept(context: ExecutionContext, next: CallHandler): Observable<any> { // 封装字段转换逻辑 const convertFields = (item: any) => { this.targetKeys.forEach((key) => { if (item[key] !== undefined) { const numValue = Number(item[key]); // 可选:避免转换失败后变成NaN,保留原始值 item[key] = isNaN(numValue) ? item[key] : numValue; } }); }; return next.handle().pipe( map((data) => { if (data?.list) { data.list.forEach(convertFields); } else if (data) { convertFields(data); } return data; }), ); } } // 使用方式:同时转换gameLevel和userScore字段 @UseInterceptors(new EnumStringToNumberInterceptor(['gameLevel', 'userScore']))
内容的提问来源于stack exchange,提问作者Ravi kant
相关产品推荐
相关产品推荐

