NestJS使用@Exclude装饰器无法排除返回参数lastSync问题求助
问题根源
你遇到的两个问题核心都是class-transformer装饰器和ClassSerializerInterceptor的作用范围没对齐:
ClassSerializerInterceptor仅负责将控制器方法最终返回的结果序列化为普通对象作为接口响应返回,完全不会处理你方法内部调用publishUpdateArming的传参@Exclude等class-transformer装饰器仅对对应类的实例生效,你传给publishUpdateArming的是普通字面量对象(仅用as UpdateArmingEvent做了编译期类型断言,运行期还是普通对象),所以装饰器规则不会生效- 你目前把
@Exclude加在了Schedule实体上,实际要序列化的是UpdateArmingEvent对象,配置加错了目标类 - 嵌套的Timeblock实例没有被序列化,是因为你没有手动触发嵌套转换逻辑
修复步骤
1. 修正@Exclude配置位置
在UpdateArmingEvent类的lastSync属性上添加排除规则,而不是仅加在Schedule实体上:
export class UpdateArmingEvent { // 其他属性省略 @Exclude({toPlainOnly : true}) lastSync: string | Date; }
2. 给pubsub传参前手动序列化
修改控制器中的调用逻辑,先将事件对象转成普通对象再传给publishUpdateArming,同时开启嵌套转换配置处理Timeblock实例:
return this.pubsub .publishUpdateArming(classToPlain({ arming: tbs.filter((t) => t.type === BlockType.ARMING), timelapse: tbs.filter((t) => t.type === BlockType.TIMELAPSE), scheduleId: ds.id, projectId: ds.projectId, lastSync: ds.lastSync, createdBy: ds.author, } as UpdateArmingEvent, { enableImplicitConversion: true, // 自动转换嵌套的类实例为普通对象 }))
如果偏好实例化类的写法,也可以替换为:
const event = new UpdateArmingEvent(); event.arming = tbs.filter(t => t.type === BlockType.ARMING); event.timelapse = tbs.filter(t => t.type === BlockType.TIMELAPSE); event.scheduleId = ds.id; event.projectId = ds.projectId; event.lastSync = ds.lastSync; event.createdBy = ds.author; return this.pubsub.publishUpdateArming(classToPlain(event));
3. 可选:嵌套对象转换优化
如果开启enableImplicitConversion后Timeblock转换仍有问题,可以给UpdateArmingEvent的数组属性加上@Type装饰器明确指定转换类型:
import { Type } from 'class-transformer'; import { Timeblock } from './timeblock.entity'; export class UpdateArmingEvent { @Type(() => Timeblock) arming: Timeblock[]; @Type(() => Timeblock) timelapse: Timeblock[]; // 其他属性省略 }
修复完成后重新运行测试即可通过。
内容的提问来源于stack exchange,提问作者sweta singh
相关产品推荐
相关产品推荐

