Declare a version of a class that has all properties as optional in TypeScript

53 Views Asked by At

I am using class-validator to do type enforcement for a Node api. I have a complex class that uses class-validator decorators, and I want to make a version of this class that represents a draft version, in which all properties are optional. Example:

export class Document {
  @IsNotEmpty()
  @Type(() => Author)
  author: Author;

  @IsNotEmpty()
  @ValidateNested({ each: true })
  @Type(() => Section)
  sections: Section[];  
}

is the original type and

export class DocumentDraft {
  @IsOptional()
  @Type(() => Author)
  author?: Author;

  @IsOptional()
  @ValidateNested({ each: true })
  @Type(() => Section)
  sections?: Section[];  
}

Sections here would have other decorated classes as properties, and those need to be optional too. The Partial generic in TS produces the desired type, but would lack class validation, right? Am I best off creating a parallel declared class with all the properties decorated with @IsOptional? Must I do this in all the nested types as well?

1

There are 1 best solutions below

0
On

This was solved by:

  1. Creating a recursive partial type:
export type RecursivePartial<T> = {
  [K in keyof T]?: RecursivePartial<T[K]>;
};

  1. Declaring a draft type that is all recursive partial:
 type DocumentDraft = RecursivePartial<Document>;
  1. Then removing all type decoration from the property containing the Document | DocumentDraft types
  class ParentType {
    document: Document | DocumentDraft;
  }

And then using Class Validator manually within the endpoint to only validate properties that exist.