This is a typescript class with an exposed but not editable attribute:
export class Category {
private _id: number;
constructor(id: number){
this._id = id;
}
public get id(){
return this._id;
}
}
I would like to map it from a JSON like this:
{ id: 1 }
There are some obvious problems here:
Object.assign(new Category(), jsonObject)
, however, this does not work since Cannot set property id of #<Category> which has only a getter
What I want to avoid is to write custom mapping logic for every class like this with private attributes, I tried some other solutions and libraries but didn't work for my situation, they're all referencing to class with only public attributes
I don't even know if what I ask is achievable, so if the case it isn't, then I will "surrender" to use the class with only public attributes
The missconception here is that you need a getter/setter at all just to manage visibility. You can't prevent code from accessing and modifying id
, no matter what you do. You can however tell the IDE (and the developer using it) that he can only read/get the property by using the readonly
modifier, which simplifies your code to:
export class Category {
readonly id: number;
}
Noe that readonly
thing only exists at compile time, and doesnt have any affects at runtime. Your IDE will prevent you from doing:
(new Category).id = 5;
But it allows you to easily do:
const category = Object.assign(new Category, { id: 5 });
Pass the object through constructor:
export class Category {
private _a: number;
private _b: string;
constructor(values: { a: number; b: string }){
this._a = values.a;
this._b = values.b;
}
public getA() { return this._a; }
public getB() { return this._b; }
}
You can still call it with or without JSON:
let cat1 = Category (values: { a: 42, b: 'hello' });
let json = '{"a":42,"b":"hello"}'
let cat2 = Category (values: JSON.parse (json));
Alternatively, keep the values in an object rather than a direct member. This makes it unnecessary to map the object to member variables:
export class Category {
private _values: {
a: number;
b: string;
}
constructor(values: { a: number; b: string }){
this._values = values;
}
public getA() { return this._values.a; }
public getB() { return this._values.b; }
}
If you want to keep the old constructor, you can do so like this:
export class Category {
private _values: {
a: number;
b: string;
}
constructor(a: number, b: string) {
this._values = { a: a, b: b };
}
public static make (values: { a: number; b: string }) {
this._values = values;
}
public getA() { return this._values.a; }
public getB() { return this._values.b; }
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.