是否可以为DTO设置默认值?

35

当查询为空时,是否有一些方法可以使用默认值?

如果我有以下用于查询的DTO:

export class MyQuery {
  readonly myQueryItem: string;
}

如果我的请求中不包含查询,那么myQuery.myQueryItem将是未定义的。我该如何使其具有默认值?

2个回答

52

您可以直接在DTO类中设置默认值:

export class MyQuery {
  readonly myQueryItem = 'mydefault';
}

你需要实例化该类,以便使用默认值。为此,您可以例如使用带有选项transform: trueValidationPipe。如果该值由您的查询参数设置,则它将被覆盖。

@Get()
@UsePipes(new ValidationPipe({ transform: true }))
getHello(@Query() query: MyQuery) {
  return query;
}

为什么这个能够工作?

1) 管道可以应用于所有的装饰器,例如 @Body(), @Param(), @Query() 并且可以转换值(例如 ParseIntPipe)或执行检查(例如 ValidationPipe)。

2) ValidationPipe 内部使用 class-validatorclass-transformer 进行验证。为了能够对您的输入(普通 JavaScript 对象)执行验证,它首先必须将它们转换为您的注释 dto 类的实例,这意味着它创建了您类的一个实例。使用设置 transform: true 将自动创建您的 dto 类的实例。

示例(基本操作方式):

class Person {
  firstname: string;
  lastname?: string = 'May';

  constructor(person) {
    Object.assign(this, person);
  }
}

// You can use Person as a type for a plain object -> no default value
const personInput: Person = { firstname: 'Yuna' };

// When an actual instance of the class is created, it uses the default value
const personInstance: Person = new Person(personInput);

我确保我的 package.json 文件中每个包都只有一个,并执行了 npm ci 命令,但是没有任何变化。 - papillon
1
请问您能解释一下ValidationPipe是如何工作的吗?目前我还不能理解它的奥妙所在。ValidationPipe是一种中间件,对吗?我可以将其应用于函数(例如我们的示例)或特定的DTO(@Query(new ValidationPipe())),对吗? transform:true具体是什么意思?为什么需要使用DTO的默认值,否则就不会使用这些默认值? 请注意,这是计算机翻译的结果,可能需要人工校对。 - papillon
这个与 class-validator 不兼容。 - EzPizza
4
这个答案是不完整的。你还需要在 ValidationPipe 的选项中设置 transformOptions: { exposeDefaultValues: true } - EzPizza
不确定为什么,但我已经按照所有建议反复验证过了,至少在NestJS common v8.4.3和class-validator v0.13.2上,我只需要将transform设置为true,就可以按照描述的那样正常工作。 - vinnymac
显示剩余2条评论

-2

在您的 Dto 中只需像这样提供一个值:

export class MyQuery {
  readonly myQueryItem: string = 'value default';
}

5
很遗憾,这对我没用。 myQueryItem仍然未定义。 - papillon
这对我也不起作用。 - Rachit Kyte.One

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接