Lets assume there is a model class like:
class Filter implements IFilterJournal {
public category: number;
public subject: number;
public teacher: number;
public mark: number;
}
I can create instance of this class:
let f = new Filter();
It returns object Filter
with empty properties inside.
How to fill properties of class more convenient?
I can determine consturctor like:
public constructor(public category: number, public subject: number, public teacher: number, public mark: number){
}
Then at the time of creation instance pass parameters:
let f = new Filter(1, 2, 3, 4)
But what if I need to fill only public subject: number;
property? either
others? How to fill them selectively?
Another was is to make parameters as optional:
public constructor(public category?: number, public subject?: number, public teacher?: number, public mark?: number){}
Then use this like:
let f = new Filter(subject = 1);
If you can initialize the object with any combination of properties, you can use a constructor that takes Partial<Filter>
as an argument, and uses Object.assign
to set the fields on the object.
class Filter {
constructor(data: Partial<Filter>){
Object.assign(this, data);
}
public category: number;
public subject: number;
public teacher: number;
public mark: number;
}
new Filter({ category: 0})
new Filter({ category: 1, subject: 2, teacher: 3, mark: 4})
Note Partial
is a mapped type that keeps the members of a type but marks all of them as Partial
. See docs. In this case Partial<Filter>
is equivalent to:
interface PartialFilter{
category?: number;
subject?: number;
teacher?: number;
mark?: number;
}
If your type has methods, Partial
would allow the argument to the constructor to contain those methods, this may be an issue. You can use conditional types to filter out methods from the argument, but it's a bit more complicated:
type NotFunctions<T> = { [P in keyof T]: T[P] extends Function ? never : P }[keyof T];
class Filter {
constructor(data: Partial<Pick<Filter, NotFunctions<Filter>>>){
Object.assign(this, data);
}
public category: number;
public subject: number;
public teacher: number;
public mark: number;
public sayHi(){ return "Hi" }
}
new Filter({ category: 0, sayHi: ()=> {}}) //Error with new constructor argument type
new Filter({ category: 0})
new Filter({ category: 1, subject: 2, teacher: 3, mark: 4})
Like C# class:
export class Filter {
category: number = null;
subject: string = null;
teacher: number = null;
mark: boolean = null;
public constructor(init?: Partial<Filter>) {
Object.assign(this, init);
}}
When you create a new instance all field names are disponible and empty.
const instance_of_filter: Filter = new Filter();
you have now a class with all fields defined :
instance_of_filter {
"category": null,
"subject": null,
"teacher": null,
"mark": null
}
You don't have to fill all the object properties right off that bat.
public constructor(public _category: number){
category = _category;
}
Would work just fine. Just keep in mind that those properties you don't fill will be undefined if you call them later before assigning them, so at the very least you may want to initialize them to some sort of acceptable value. Perhaps:
public constructor(public _category: number){
this.category = _category;
this.subject = 0;
this.teacher = 0;
//etc...
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With