Skip to content

Instantly share code, notes, and snippets.

@kazuhito-m
Last active August 23, 2020 20:07
Show Gist options
  • Save kazuhito-m/97e86f776cc2b27fdf5f966a277a21d4 to your computer and use it in GitHub Desktop.
Save kazuhito-m/97e86f776cc2b27fdf5f966a277a21d4 to your computer and use it in GitHub Desktop.
export default class Sreializer {
private readonly constructors: ObjectConstructor[];
constructor(...constructors: any) {
this.constructors = constructors;
}
public serialize(target: any): string {
this.addClassNameProperty(target); // TODO 元のオブジェクトを上書きまくるのでなんとかしたい
return JSON.stringify(target, null, 4);
}
public deserialize(json: string): any {
const obj = JSON.parse(json);
return this.toClassInstance(obj);
}
private addClassNameProperty(value: any): void {
if (typeof value !== "object") return;
if (Array.isArray(value)) return value.forEach(i => this.addClassNameProperty(i));
value.__CLASS_NAME = value.constructor.name;
for (var key in value) {
if (value.hasOwnProperty(key)) {
this.addClassNameProperty(value[key]);
}
}
}
private toClassInstance(value: any): any {
if (typeof value !== "object") return value;
if (Array.isArray(value)) return value.map(i => this.toClassInstance(i));
if (!value.__CLASS_NAME) return value;
if (value.__CLASS_NAME === "Object") return value;
const obj = this.createInstanceOf(value.__CLASS_NAME);
if (!obj) return obj;
for (let key in value) {
if (value.hasOwnProperty(key)) {
const inValue = value[key];
obj[key] = this.toClassInstance(inValue);
}
}
return obj;
}
private createInstanceOf(className: string): any {
const foundCons = this.constructors
.find(cons => className === cons.name);
if (!foundCons) return null;
return new foundCons();
}
}
import Serializer from './Serializer';
export default class Test {
public test() {
const src = new SerializeTarget(12, 34, [
new Child("これ"),
new Child("でてれば"),
new Child("OK")
]);
const serializer = new Serializer(SerializeTarget, Child);
const text = serializer.serialize(src);
alert(text);
const dist = serializer.deserialize(text) as SerializeTarget;
alert(dist.calc());
alert(dist.message());
alert(dist.childrenMethod[0].testText());
}
}
export class SerializeTarget {
constructor(
private readonly x: number,
private readonly y: number,
children: Child[]
) {
this.children = children;
}
children: Child[];
public calc() {
return this.x + this.y;
}
public message() {
return this.children.map(i => i.text).join();
}
public get childrenMethod() {
return this.children;
}
}
export class Child {
constructor(public readonly text: string) { }
public testText() {
return ("このはなしは" + this.text + "と表示されれば、お子のメソッドも復元している。");
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment