Отображение объекта JSON String / JS в класс Typescript с закрытыми атрибутами - PullRequest
0 голосов
/ 05 ноября 2018

Это класс машинописного текста с открытым, но не редактируемым атрибутом:

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

Чего я хочу избежать, так это написать собственную логику отображения для каждого класса, подобную этой, с закрытыми атрибутами, я пробовал некоторые другие решения и библиотеки, но не работал для моей ситуации, они все ссылаются на класс только с открытыми атрибутами

Я даже не знаю, достижимо ли то, что я спрашиваю, поэтому, если это не так, тогда я "сдаюсь", чтобы использовать класс только с открытыми атрибутами

Ответы [ 2 ]

0 голосов
/ 05 ноября 2018

Ошибочное мнение здесь в том, что вам нужен вообще геттер / сеттер только для управления видимостью. Вы не можете запретить доступ к коду и его изменение id, независимо от того, что вы делаете. Однако вы можете сообщить IDE (и разработчику, использующему его), что он может только читать / получать свойство, используя модификатор readonly, который упрощает ваш код до:

 export class Category {
   readonly id: number;
 }

Нет, readonly существует только во время компиляции и не оказывает влияния во время выполнения. Ваша IDE не позволит вам сделать:

 (new Category).id = 5;

Но это позволяет легко сделать:

 const category = Object.assign(new Category, { id: 5 });
0 голосов
/ 05 ноября 2018

Передача объекта через конструктор:

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; }
}
...