首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >带有InterestionType/PickType的NestJS DTO解码器仍然在字段应该是可选的时候执行isDefined()验证

带有InterestionType/PickType的NestJS DTO解码器仍然在字段应该是可选的时候执行isDefined()验证
EN

Stack Overflow用户
提问于 2022-09-19 18:58:53
回答 1查看 27关注 0票数 1

我正在通过IntersectionType处理DTO验证,并尝试从另一个DTO添加一个可选字段,使用PickType组合。例如,我创建了一个AdminCodeDTO,这基本上是我在应用程序中使用AdminCode的所有规则,因此数字范围是一致的,以及任何其他定义。

代码语言:javascript
运行
复制
export class AdminCodeDTO {
    @IsDefined() @IsNumber() @Min(1) @Max(999) public AdminCode: number;
    constructor(AdminCode?: number) {
        this.AdminCode = AdminCode;
    }
}

测试工作正常,验证确实运行。

代码语言:javascript
运行
复制
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来包含它。

代码语言:javascript
运行
复制
export class TimeEntryDTO extends IntersectionType (
    AdminCodeDTO,
    OtherDTO
) {}

在上面的例子中,我的AdminCodeDTO现在是OtherDTO的一部分,所有的验证都正常工作。这和预期的一样工作,需要我的AdminCode,包括所有的验证规则。

现在我有一个例子,我希望AdminCodeDTO验证是存在的,但前提是字段已经填充。该字段不再是必需的,而是可选的。我相信PickType是为了这个。因此,我想我可以做到:

代码语言:javascript
运行
复制
export class TimeEntryDTO extends IntersectionType (
    PickType(AdminCodeDTO, ['AdminCode'] as const),
    TimeDetailDTO,
) {}

我本以为现在可以将我的TimeDetailDTO,然后是AdminCode字段作为可选的。但是,验证会导致问题,因为当我不提供AdminCode时,@isDefined()会失败。

代码语言:javascript
运行
复制
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字段现在在类中可能是可选的,但验证装饰器在加载时仍然被使用。

因此,在这个场景中是否有一种删除装饰器的方法?是否有一种方法可以添加一个,这样我就可以从AdminCodeDTO中删除它,然后在需要强制执行AdminCode规则时添加它(比如定义AdminCode)?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2022-09-20 15:28:27

PickType只选择数组中指定的字段,如果字段是可选的或不是可选的,则不会修改。您可以将PickType封装在PartialType中,使该字段可以选择PartialType(PickType(AdminCodeDTO, ['AdminCode'] as const))

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/73778126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档