Zusammenfassung: Eine Zeile
// Dies setzt voraus, dass Ihre Konstruktormethode Eigenschaften aus dem Argument zuweist.
.map((instanceData: MyClass) => new MyClass(instanceData));
Die Ausführliche Antwort
Ich würde die Object.assign-Methode nicht empfehlen, da sie Ihren Klasseninstanz unangemessen mit irrelevanten Eigenschaften (sowie definierten Closures) versehen kann, die nicht innerhalb der Klasse selbst deklariert wurden.
In der Klasse, in die Sie deserialisieren möchten, sollten Sie sicherstellen, dass alle zu deserialisierenden Eigenschaften definiert sind (null, leeres Array, etc). Indem Sie Ihre Eigenschaften mit Anfangswerten definieren, machen Sie ihre Sichtbarkeit beim Versuch, Klassenmember zu iterieren und Werte zuzuweisen, sichtbar (siehe Methode deserialize unten).
export class Person {
public name: string = null;
public favoriteSites: string[] = [];
private age: number = null;
private id: number = null;
private active: boolean;
constructor(instanceData?: Person) {
if (instanceData) {
this.deserialize(instanceData);
}
}
private deserialize(instanceData: Person) {
// Beachten Sie, dass this.active nicht in keys aufgeführt wird, da es deklariert, aber nicht definiert ist
const keys = Object.keys(this);
for (const key of keys) {
if (instanceData.hasOwnProperty(key)) {
this[key] = instanceData[key];
}
}
}
}
In dem obigen Beispiel habe ich einfach eine deserialize-Methode erstellt. In einem echten Beispiel würde ich sie in einer wiederverwendbaren Basisklasse oder Servicemethode zentralisiert haben.
So verwenden Sie dies beispielsweise in einer http-Antwort...
this.http.get(ENDPOINT_URL)
.map(res => res.json())
.map((resp: Person) => new Person(resp) ) );
Wenn tslint/ide sich über den nicht kompatiblen Argumenttyp beschwert, wandeln Sie das Argument einfach in denselben Typ um, indem Sie spitze Klammern verwenden, Beispiel:
const person = new Person( { name: 'John', age: 35, id: 1 });
Wenn Sie Klassenmember haben, die von einem bestimmten Typ sind (aka: Instanz einer anderen Klasse), können Sie sie über Getter/Setter-Methoden in typisierte Instanzen umwandeln.
export class Person {
private _acct: UserAcct = null;
private _tasks: Task[] = [];
// Konstruktor- & Deserialisierungsmethoden...
public get acct(): UserAcct {
return this.acct;
}
public set acct(acctData: UserAcct) {
this._acct = new UserAcct(acctData);
}
public get tasks(): Task[] {
return this._tasks;
}
public set tasks(taskData: Task[]) {
this._tasks = taskData.map(task => new Task(task));
}
}
Das obige Beispiel wird sowohl acct als auch die Liste der tasks in ihre jeweiligen Klasseninstanzen deserialisieren.