You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 20:55:21