禁止 Nestjs 中 DTO 的特定枚举值

9 class-validator nestjs

我的“AppState”枚举具有以下可能的枚举值:

export enum AppState {
  SUCCESS,
  ERROR,
  RUNNING
}
Run Code Online (Sandbox Code Playgroud)

我有一个UpdateAppStateDTOappState它应该接受除RUNNING之外的每个枚举值。

export class UpdateAppStateDTO {
  @IsEnum(AppState)
  @NotEquals(AppState.RUNNING) // Doesn't work properly
  public appState: AppState;
}
Run Code Online (Sandbox Code Playgroud)

对于路线我有这个例子

  @Patch()
  public setState(@Body() { appState }: UpdateAppStateDTO): void {
    console.log(appState);
  }
Run Code Online (Sandbox Code Playgroud)

如果请求有一个空的正文或一个无效的枚举值,比如“foobar”,appState因为我得到了 400,这很好。

问题是当我发送“RUNNING”时,我仍然得到 200 而不是 400。

我怎样才能防止这种行为?

Jay*_*iel 12

我假设您正在发送 string 'RUNNING',并且您正在尝试确保未使用该字符串,对吗?使用您目前所拥有的,您的枚举映射到这些值:

export enum AppState {
  SUCCESS = 0,
  ERROR = 1,
  RUNNING = 2
}
Run Code Online (Sandbox Code Playgroud)

因此,如果您发送 string 'RUNNING',验证器会检查RUNNING !== 2实际上true导致成功验证的内容。该@IsEnum()装饰检查值发送中的枚举有效的关键,在这样发送'RUNNING'通行证,办理入住手续,因此为什么你没有得到某种形式的错误的。

解决这个问题的最详细的方法是让你的枚举string enum像这样:

export enum AppState {
  SUCCESS = 'SUCCESS',
  ERROR = 'ERROR',
  RUNNING = 'RUNNING'
}
Run Code Online (Sandbox Code Playgroud)

这将使每个AppState值映射到其相应的字符串,尽管这确实导致必须键入大量声明并可能导致重复代码。管理此问题的另一种方法是将@NotEquals()枚举设置为枚举值提供的键,如下所示:

export class UpdateAppStateDTO {
  @IsEnum(AppState)
  @NotEquals(AppState[AppState.RUNNING])
  public appState: AppState;
}
Run Code Online (Sandbox Code Playgroud)

但请记住,使用这种方法,当您appState稍后查看时,它仍然是数值而不是字符串。

您可以使用我为此制作的stackblitz来查看一些正在运行的代码。