将 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 }

这里有一些明显的问题:

我想避免的是为每个 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 });