将 JSON String/JS 对象映射到具有私有属性的 Typescript class
Mapping JSON String/JS object to Typescript class with private attributes
这是一个打字稿class,具有公开但不可编辑的属性:
export class Category {
private _id: number;
constructor(id: number){
this._id = id;
}
public get id(){
return this._id;
}
}
我想像这样从 JSON 映射它:
{ id: 1 }
这里有一些明显的问题:
- 我知道“_id”不能神奇地映射到 "id" 所以也许我可以实现一个自定义逻辑,在名称
前用 _ 重命名所有属性
- 我想保留带有 id 参数的构造函数,但也许我无法在实例化之前映射需要参数的对象
- 使用空构造函数,我尝试了
Object.assign(new Category(), jsonObject)
,但是,这不起作用,因为 Cannot set property id of #<Category> which has only a getter
我想避免的是为每个 class 编写带有私有属性的自定义映射逻辑,我尝试了一些其他解决方案和库,但对我的情况不起作用,它们都在引用到 class 只有 public 个属性
我什至不知道我的要求是否可以实现,所以如果不能实现,那么我将 "surrender" 仅使用 class public属性
通过构造函数传递对象:
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; }
}
无论有没有JSON你仍然可以调用它:
let cat1 = Category (values: { a: 42, b: 'hello' });
let json = '{"a":42,"b":"hello"}'
let cat2 = Category (values: JSON.parse (json));
或者,将值保存在对象而不是直接成员中。这样就不需要将对象映射到成员变量了:
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; }
}
如果你想保留旧的构造函数,你可以这样做:
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; }
}
这里的误解是您根本需要 getter/setter 来管理可见性。无论您做什么,都无法阻止代码访问和修改 id
。但是,您可以使用 readonly
修饰符告诉 IDE(以及使用它的开发人员)他只能 read/get 属性,这将您的代码简化为:
export class Category {
readonly id: number;
}
注意 readonly
东西只存在于编译时,在运行时没有任何影响。你的 IDE 会阻止你做:
(new Category).id = 5;
但它可以让你轻松做到:
const category = Object.assign(new Category, { id: 5 });
这是一个打字稿class,具有公开但不可编辑的属性:
export class Category {
private _id: number;
constructor(id: number){
this._id = id;
}
public get id(){
return this._id;
}
}
我想像这样从 JSON 映射它:
{ id: 1 }
这里有一些明显的问题:
- 我知道“_id”不能神奇地映射到 "id" 所以也许我可以实现一个自定义逻辑,在名称 前用 _ 重命名所有属性
- 我想保留带有 id 参数的构造函数,但也许我无法在实例化之前映射需要参数的对象
- 使用空构造函数,我尝试了
Object.assign(new Category(), jsonObject)
,但是,这不起作用,因为Cannot set property id of #<Category> which has only a getter
我想避免的是为每个 class 编写带有私有属性的自定义映射逻辑,我尝试了一些其他解决方案和库,但对我的情况不起作用,它们都在引用到 class 只有 public 个属性
我什至不知道我的要求是否可以实现,所以如果不能实现,那么我将 "surrender" 仅使用 class public属性
通过构造函数传递对象:
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; }
}
无论有没有JSON你仍然可以调用它:
let cat1 = Category (values: { a: 42, b: 'hello' });
let json = '{"a":42,"b":"hello"}'
let cat2 = Category (values: JSON.parse (json));
或者,将值保存在对象而不是直接成员中。这样就不需要将对象映射到成员变量了:
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; }
}
如果你想保留旧的构造函数,你可以这样做:
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; }
}
这里的误解是您根本需要 getter/setter 来管理可见性。无论您做什么,都无法阻止代码访问和修改 id
。但是,您可以使用 readonly
修饰符告诉 IDE(以及使用它的开发人员)他只能 read/get 属性,这将您的代码简化为:
export class Category {
readonly id: number;
}
注意 readonly
东西只存在于编译时,在运行时没有任何影响。你的 IDE 会阻止你做:
(new Category).id = 5;
但它可以让你轻松做到:
const category = Object.assign(new Category, { id: 5 });