Skip to content

Instantly share code, notes, and snippets.

@Mefistophell
Created July 24, 2024 11:32
Show Gist options
  • Save Mefistophell/07d63b44d69d38af9406bc59a35c3ec7 to your computer and use it in GitHub Desktop.
Save Mefistophell/07d63b44d69d38af9406bc59a35c3ec7 to your computer and use it in GitHub Desktop.
ts-decorator-metadata
// Another way is to use const serializables = Symbol();
const serializables = new WeakMap<object, string[]>();
type Context =
| ClassAccessorDecoratorContext
| ClassGetterDecoratorContext
| ClassFieldDecoratorContext
;
function serialize(_target: any, context: Context): void {
if (context.static || context.private) {
throw new Error("Can only serialize public instance members.")
}
if (typeof context.name !== "string") {
throw new Error("Can only serialize string properties.");
}
// if Symbol used: const propNames = (context.metadata[serializables] as string[] | undefined) ??= [];
let propNames = serializables.get(context.metadata || {});
if (propNames === undefined) {
serializables.set(context.metadata || {}, propNames = []);
}
propNames.push(context.name);
}
function jsonify(instance: object): string {
// @ts-ignore
const metadata = instance.constructor[Symbol.metadata];
// if Symbol used: const propNames = metadata?.[serializables] as string[] | undefined;
const propNames = metadata && serializables.get(metadata);
if (!propNames) {
throw new Error("No members marked with @serialize.");
}
const pairStrings = propNames.map((key: string) => {
const strKey = JSON.stringify(key);
const strValue = JSON.stringify((instance as any)[key]);
return `${strKey}: ${strValue}`;
});
return `{ ${pairStrings.join(", ")} }`;
}
class Person {
firstName: string;
lastName: string;
@serialize
age: number
@serialize
get fullName() {
return `${this.firstName} ${this.lastName}`;
}
toJSON() {
return jsonify(this)
}
constructor(firstName: string, lastName: string, age: number) {
this.firstName = firstName
this.lastName = lastName
this.age = age
}
}
const person = new Person('Alice', 'Sofia', 4)
console.log(person.toJSON())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment