Reputation: 7212
This is a simplified example:
class PersonParms{
name:string;
lastName:string;
age?:number;
get fullName(){return this.name + " " + this.lastName;}
}
class Person{
constructor(prms:PersonParms){
}
}
new Person({name:'John',lastName:'Doe'}) // ts error: Property 'fullName' is missing in type '{ name: string; lastName: string; }'.
The idea is to pass a literal object as the intizalizer of PersonParms but having that getter you can neither declare the getter optional or add the property to the object literal. Is there another way to achieve it?
Upvotes: 17
Views: 16473
Reputation: 1
If you don't want to make every property optional using Partial, you can just omit the getters.
class PersonParms{
name:string;
lastName:string;
age?:number;
get fullName(){return this.name + " " + this.lastName;}
}
class Person{
constructor(prms: Omit<PersonParms, 'fullName'> ){
}
}
new Person({name:'John',lastName:'Doe'})
Upvotes: 0
Reputation: 17702
Remember that optional is a type concept. A getter is an implementation. The implementation can return an optional type. In a class that implements an interface with an optional readonly property, the class may leave off the getter. See this answer get and set in TypeScript
Upvotes: 1
Reputation: 91
If you cast the object this will prevent the compile time error.
export class IndividualModel {
constructor(individual: IndividualModel = null) {
if (individual) {
this.individualKey = individual.individualKey;
this.firstName = individual.firstName;
this.lastName = individual.lastName;
}
}
individualKey: string;
firstName?: string;
lastName?: string;
get fullName(): string {
return `${this.lastName}, ${this.firstName}`;
}
}
const individual = new IndividualModel(<IndividualModel>{ individualKey: 'some-key' });
Upvotes: 0
Reputation: 1273
As of April 2020, there is NO way to implement this.
There is an inconclusive PR for this: https://github.com/microsoft/TypeScript/pull/16344
A proposed solution via an interface is presented here: https://github.com/microsoft/TypeScript/pull/16344
Personally, the solution did not meet my needs, and I rather declared the property as private.
Hopefully, we can have better luck in the future.
Upvotes: 6
Reputation: 7005
If you creates a new instance of PersonParms then the error will be gone.
class PersonParms{
name:string;
lastName:string;
age?:number;
get fullName(){return this.name + " "+this.lastName;}
}
class Person{
constructor(prms:PersonParms){
}
}
const personParams = new PersonParms();
personParams.name = 'John';
personParams.lastName = 'John';
new Person(personParams) // No error because this is an instance of PersonParams
I am not sure where/how do you use PersonParms.fullname but in your case I would use this:
interface PersonParms{
name:string;
lastName:string;
age?:number;
}
class Person implements PersonParms{
name: string;
lastName: string;
age?:number
constructor(prms: PersonParms) {
this.name = prms.name;
this.lastName = prms.lastName;
this.age = prms.age;
}
get fullName(){return this.name + " "+this.lastName;}
}
const person = new Person({ name: 'John', lastName: 'Doe' });
console.log(person.fullName); // John Doe
Upvotes: 1
Reputation: 696
I found this solution which is ok for me:
class Person {
name?:string;
lastName?:string;
age?: number;
fullName?:string;
constructor(public config: { name: string, lastName: string }) {
Object.defineProperty(this,'fullName',{
get(){return this.name + " " + this.lastName;}
});
}
Upvotes: 2
Reputation: 52
class PersonParms {
name: string;
lastName: string;
age?: number;
getFullName?(): string | null { return this.name + ' ' + this.lastName; }
}
class Person {
constructor(prms: PersonParms) {
}
}
new Person({ name: 'John', lastName: 'Doe' });
Upvotes: -3
Reputation: 52
class PersonParms {
name: string;
lastName: string;
age?: number;
fullName?: string = this.name + ' ' + this.lastName;
}
class Person {
constructor(prms: PersonParms) {
}
}
new Person({ name: 'John', lastName: 'Doe' });
Upvotes: 0
Reputation: 2554
Very interesting. I think, you should report an issue to TypeScript, because methods can be optional (see below), but property getters not. It is strange.. As a workaround I can suggest two variants. A nice one:
class PersonParms {
name:string;
lastName:string;
age?: number;
getFullName?() {return this.name + " "+this.lastName;}
}
And a second one, that is hacky, because there we make all the properties optional when passing to constructor.
class PersonParms {
name:string;
lastName:string;
age?: number;
get fullName(){return this.name + " "+this.lastName;}
}
class Person{
constructor(prms: Partial<PersonParms>){
}
}
Upvotes: 13
Reputation: 275847
Is there another way to achieve it?
Here is how I would do it:
class Person {
constructor(public config: { name: string, lastName: string }) {}
age?: number;
get fullName() { return this.config.name + " " + this.config.lastName; }
}
new Person({ name: 'John', lastName: 'Doe' })
Upvotes: 2