如何在NestJS中自定义Swagger DTO映射类型实现部分字段可选?
NestJS 自定义Swagger DTO映射类型:指定字段设为可选且复用
问题背景
需要在NestJS中创建可复用的Swagger DTO映射类型,要求保留原DTO的所有字段,仅将指定字段设为可选。原有的写法可行但复用性差:
export default class CreateUserDto extends IntersectionType( OmitType(UserDto, ['nickname'] as const), PartialType(PickType(UserDto, ['nickname'] as const)), ) {}
尝试封装成可复用函数时遇到报错:
const OptionalType = (dto, optional) => { return class NewClass extends IntersectionType( OmitType(dto, optional as const), PartialType(PickType(dto, optional as const)), ) {}; }; export default class CreateUserDto extends OptionalType(UserDto, [ 'nickname', ]) {}
报错信息:
A 'const' assertions can only be applied to references to enum members, or string, number, boolean, array, or object literals.
解决方案
错误原因是optional作为函数参数属于变量引用,而非字面量,无法直接使用as const断言。通过泛型约束和类型推断可以解决这个问题,同时保证类型安全:
import { IntersectionType, OmitType, PartialType, PickType } from '@nestjs/mapped-types'; // 泛型函数:T为原DTO类型,K为要设为可选的字段集合 export const OptionalType = <T, K extends keyof T>( dto: new () => T, optionalFields: readonly K[] ) => { return class extends IntersectionType( OmitType(dto, optionalFields), PartialType(PickType(dto, optionalFields)) ) {}; }; // 使用示例:传入字段数组时加as const,让TypeScript捕获字面量类型 export class CreateUserDto extends OptionalType(UserDto, ['nickname'] as const) {}
说明
- 泛型
K extends keyof T确保传入的字段名一定是原DTO的有效字段,避免拼写错误 - 参数
optionalFields声明为readonly K[],配合调用时的as const,让TypeScript正确推断字段的字面量类型,满足OmitType和PickType的类型要求 - 封装后的
OptionalType可以重复用于任意DTO,只需传入目标DTO类和要设为可选的字段数组
内容的提问来源于stack exchange,提问作者Andreina Riera
相关产品推荐
相关产品推荐

