簡體   English   中英

當字段應該是可選的時,帶有 InterestionType/PickType 的 NestJS DTO 裝飾器仍然強制執行 isDefined() 驗證

[英]NestJS DTO Decorators with InterestionType/PickType still enforcing isDefined() validation when field should be optional

我正在通過 IntersectionType 進行 DTO 驗證,並嘗試使用 PickType 組合從另一個 DTO 添加可選字段。 例如,我創建了一個 AdminCodeDTO,這基本上是我在應用程序中使用 AdminCode 的所有規則,因此數字范圍和任何其他定義都是一致的。

export class AdminCodeDTO {
    @IsDefined() @IsNumber() @Min(1) @Max(999) public AdminCode: number;
    constructor(AdminCode?: number) {
        this.AdminCode = AdminCode;
    }
}
    

測試工作正常,驗證確實運行。

it('should generate the DTO errors', async () => {
    const DTOValidCheck: AdminCodeDTO = new AdminCodeDTO();
    const Errors: Array<ValidationError> = await validate(DTOValidCheck);
    expect(Errors.length).toBe(1);
    expect(Errors[0].constraints['isDefined']).toBe('AdminCode should not be null or undefined');
    expect(Errors[0].constraints['isNumber']).toBe('AdminCode must be a number conforming to  the specified constraints');
    expect(Errors[0].constraints['max']).toBe('AdminCode must not be greater than 999');
    expect(Errors[0].constraints['min']).toBe('AdminCode must not be less than 1');
});

我現在有另一個包含其他數據的 DTO,加上 AdminCode,所以我使用 IntersectionType 來包含它。

export class TimeEntryDTO extends IntersectionType (
    AdminCodeDTO,
    OtherDTO
) {}

在上述情況下,我的 AdminCodeDTO 現在是 OtherDTO 的一部分,並且所有驗證工作正常。 這按預期工作,我的 AdminCode 是必需的,包括所有驗證規則。

現在我有一個案例,我希望存在 AdminCodeDTO 驗證,但前提是填充了該字段。 該字段不再是必需的,而是可選的。 我相信 PickType 就是為此而生的。 因此,我認為我可以這樣做:

export class TimeEntryDTO extends IntersectionType (
    PickType(AdminCodeDTO, ['AdminCode'] as const),
    TimeDetailDTO,
) {}

我本來希望現在有我的 TimeDetailDTO,然后是 AdminCode 字段,作為可選的。 情況確實如此,因為包含該字段,但是,當我不提供 AdminCode 時,驗證會導致問題,因為 @isDefined() 失敗。

it('should not generate the AdminCode errors when AdminCode is not set', async () => {
    TestDTO.AdminCode = undefined;
    const Errors: Array<ValidationError> = await validate(TestDTO);
    expect(Errors.length).toBe(0); // This should be the case, but it is returning all the validation
    // The following errors are all returned, which I thought the PickType would have made the field optional, so the IsDefined() should not be processed.
    expect(Errors[0].constraints['isDefined']).toBe('AdminCode should not be null or undefined');
    expect(Errors[0].constraints['isNumber']).toBe('AdminCode must be a number conforming to the specified constraints');
    expect(Errors[0].constraints['max']).toBe('AdminCode must not be greater than 999');
    expect(Errors[0].constraints['min']).toBe('AdminCode must not be less than 1');
});

但是,我確實相信 InterestionType 結合了所有這些,雖然 AdminCode 字段現在在 class 中可能是可選的,但驗證裝飾器在加載時仍然使用。

因此,有沒有辦法在這種情況下刪除裝飾器? 有沒有辦法添加一個,以便我可以從 AdminCodeDTO 中刪除它,然后在我想要強制執行 AdminCode 規則時添加它(例如定義 AdminCode)?

PickType只選擇數組中指定的字段,不修改該字段是否可選。 您可以將PartialType包裝在PickType中,以使該字段被選中並且是可選的。 PartialType(PickType(AdminCodeDTO, ['AdminCode'] as const))

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM