如何在TypeScript中为带class-validator的类生成全可选草稿版本?
使用class-validator生成可选属性草稿类的疑问
我正在用class-validator为Node API做类型校验,现有一个带有class-validator装饰器的复杂类,希望生成一个所有属性均为可选的草稿版本。示例如下:
原始类
export class Document { @IsNotEmpty() @Type(() => Author) author: Author; @IsNotEmpty() @ValidateNested({ each: true }) @Type(() => Section) sections: Section[]; }
目标草稿类
export class DocumentDraft { @IsOptional() @Type(() => Author) author?: Author; @IsOptional() @ValidateNested({ each: true }) @Type(() => Section) sections?: Section[]; }
其中Section还包含其他带装饰器的类属性,这些属性也需要设为可选。我有以下几个问题:
- TypeScript的Partial泛型能生成所需类型,但会缺少类校验,对吗?
- 我是否最好创建一个并行类,为所有属性添加@IsOptional装饰器?
- 嵌套类型也必须这样处理吗?
解答
Partial泛型的局限
没错,Partial<Document>确实能生成所有属性可选的TypeScript类型,但它仅停留在类型定义层面,完全无法保留class-validator依赖的装饰器元数据。class-validator的校验逻辑是基于类实例上的装饰器信息实现的,而Partial生成的只是一个无任何元数据的接口,根本无法用于校验。并行类方案的合理性
这是最可靠的解决方案。因为class-validator的校验逻辑与类强绑定,通过创建对应的Draft并行类,给每个属性手动添加@IsOptional()装饰器,同时保留@Type()、@ValidateNested()这类必要的校验装饰器,才能确保整个校验流程正常运作。
如果类的结构非常复杂,手动编写并行类会产生大量冗余代码,这时可以考虑用装饰器工厂或者代码生成工具自动生成Draft类,减少重复劳动。
- 嵌套类型的处理要求
是的,嵌套类型必须同步处理。比如你的Section类,如果在草稿场景下它的所有属性也需要可选,就必须创建SectionDraft类,给它的每个属性添加@IsOptional()装饰器,然后在DocumentDraft的sections属性的@Type()装饰器中指向SectionDraft而非原Section类。否则嵌套属性会沿用原类的非空校验规则,不符合草稿类的需求。
调整后的示例代码如下:
// 假设已创建AuthorDraft和SectionDraft类 export class DocumentDraft { @IsOptional() @Type(() => AuthorDraft) author?: AuthorDraft; @IsOptional() @ValidateNested({ each: true }) @Type(() => SectionDraft) sections?: SectionDraft[]; }
内容的提问来源于stack exchange,提问作者Jay Schroeder
相关产品推荐
相关产品推荐

