La valeur par défaut {} ne correspond pas au type CustomArgs. Il suffit de créer une constante avec les valeurs par défaut ou plus simplement marquer toutes les propriétés comme optionnelles.
Grâce au Duck Typing, nous obtenons une "factory" gratuitement :
/* Default. */customer =newCustomer();/* Partial. */customer =newCustomer({ firstName:'Foo'});/* Deserializer. */constdata=JSON.parse('...');// Instead of new Customer(data.firstName, data.lastName)customer =newCustomer(data); /* Copy. */customer =newCustomer(customer);// error TS2345: Argument of type '{ firstName: string; lastName: string; email: string; }' is not assignable to parameter of type 'Customer'.
// Object literal may only specify known properties, and 'email' does not exist in type 'Customer'.customer =newCustomer({ firstName:'Foo', lastName:'BAR', email:'foo.bar@wishtack.com'});
Entity schema
Si on change la signature de la classe Customer, paf ! ça casse tout !
classCustomer { firstName?:string; lastName?:string;// error TS2322: Type '{}' is not assignable to type 'Customer'.// Property 'getName' is missing in type '{}'.constructor(args:Customer= {}) {this.firstName =args.firstName;this.lastName =args.lastName; }getName() {return`${this.firstName}${this.lastName}`; }}
Dans ce cas, la solution ne nécessite qu'un léger refactoring local en séparant la description de l'entité avec le constructeur dans la classe CustomerSchema puis les méthodes dans la classe Customer.
classCustomerSchema { firstName?:string; lastName?:string;// error TS2322: Type '{}' is not assignable to type 'Customer'.// Property 'getName' is missing in type '{}'.constructor(args:CustomerSchema= {}) {this.firstName =args.firstName;this.lastName =args.lastName; }}classCustomerextendsCustomerSchema {getName() {return`${this.firstName}${this.lastName}`; }}
Dans une approche plus fonctionnelle et avec un souci de séparation des responsabilités, la méthode Customer.getName pourrait être déplacée dans une classe CustomerHelper: