Skip to content

Instantly share code, notes, and snippets.

@sergiodxa
Last active May 26, 2021 01:50
Show Gist options
  • Save sergiodxa/2e1fd60fab1bfee331192ce13fab6d3b to your computer and use it in GitHub Desktop.
Save sergiodxa/2e1fd60fab1bfee331192ce13fab6d3b to your computer and use it in GitHub Desktop.
Serializer in TS similar to ActiveModel::Serializer
abstract class Serializer {
abstract attributes: string[];
[customAttribute: string]: unknown; // this allow this[attribute] to work so we can use getters to add extra attributes
constructor(protected input: Record<string, unknown>) {}
private filterAttributes() {
return Object.fromEntries(
this.attributes.map((attribute) => {
return [attribute, this.input[attribute] ?? this[attribute]];
})
);
}
toJSON() {
return this.filterAttributes();
}
toString() {
return JSON.stringify(this);
}
}
class UserSerializer extends Serializer {
attributes = ["firstName", "lastName", "fullName"];
protected get fullName() {
return `${this.input.firstName} ${this.input.lastName}`;
}
}
console.log(
JSON.stringify(
new UserSerializer({
token: "1.2.3",
firstName: "Sergio",
lastName: "Xalambrí", // if I remove this, TS should throw, how could I do that?
})
)
);
console.log(
new UserSerializer({
token: "1.2.3",
firstName: "Sergio",
lastName: "Xalambrí",
}).toString() // calling this is the same as manually calling JSON.stringify
);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment