I'm a little new to Typescript, I'm using Typescript 4.4 and I know of Utility types (Pick, Omit, Partial, ...). These however only work on types and interfaces and not on classes. I cannot use interfaces as I'm using TypeGraphQL and that framework expects classes instead of interfaces.
To minimize code duplication, I'm trying to do the following:
class User {
id!: string;
firstName!: string;
lastName!: string;
email!: string;
street?:string;
... many more fields
}
class UserForUpdate extends Partial<User> {} //fails with 'Partial' only refers to a type, but is being used as a value here
or
class UserForUpdate extends User {
id?: string; //fails with Type 'string | undefined' is not assignable to type 'string'.
firstName?: string; //fails with Type 'string | undefined' is not assignable to type 'string'.
lastName?: string; //fails with Type 'string | undefined' is not assignable to type 'string'.
email?: string; //fails with Type 'string | undefined' is not assignable to type 'string'.
}
I also tried the following:
function forUpdating<T extends { new (...args: any[]) : any, prototype: any }>(ctor: T): Partial<T> & { new (...args: any[]): T } {
return ctor as any;
}
export class TestUser extends forUpdating(User) {
// fails with The types of 'prototype.id' are incompatible between these types.
// Type 'string | undefined' is not assignable to type 'string'.
// Type 'undefined' is not assignable to type 'string'.
id?: string;
firstName?: string;
lastName?: string;
email?: string;
}
Is there an easy way to make all required properties of a class optional?
CodePudding user response:
If your class only contains fields I would generally not recomend actually creating a class, you are much better off using an interface
class User {
id!: string;
firstName!: string;
lastName!: string;
email!: string;
street?:string;
}
interface UserForUpdate extends Partial<User> {}
const user: UserForUpdate = {
id: "",
}
If you want to bring in the fields from the interface to class you can use interface - class merging:
class User {
id!: string;
firstName!: string;
lastName!: string;
email!: string;
street?:string;
}
interface UserForUpdate extends Partial<User> {}
class UserForUpdate {
}
const user: UserForUpdate = new UserForUpdate()
user.email = ""