Skip to content

Instantly share code, notes, and snippets.

@louishuyng
Created April 16, 2024 04:18
Show Gist options
  • Save louishuyng/1a4bd7736f8cf4199460a7d9587cf7da to your computer and use it in GitHub Desktop.
Save louishuyng/1a4bd7736f8cf4199460a7d9587cf7da to your computer and use it in GitHub Desktop.
Model on FE
import { Profile } from "./profile";
import { User } from "./user";
const types = {
user: User,
profile: Profile,
};
export class Model {
static fromJson<
Value extends InstanceType<typeof types[T]>,
T extends keyof typeof types
>(json: { type: T; [key: string]: any }): Value;
static fromJson<
Value extends InstanceType<typeof types[T]>,
T extends keyof typeof types
>(json: { type: T; [key: string]: any }[]): Value[];
static fromJson(json: any): any {
if (Array.isArray(json)) {
return Model.fromJsonArray(json);
}
return Model.fromJsonSingle(json);
}
private static fromJsonArray<
Value extends InstanceType<typeof types[T]>,
T extends keyof typeof types
>(json: Array<{ [key: string]: any; type: T }>): Value[] {
return json.map((item) => Model.fromJsonSingle(item));
}
private static fromJsonSingle<
Value extends InstanceType<typeof types[T]>,
T extends keyof typeof types
>(json: { [key: string]: any; type: T }): Value {
const type = json["type"] as keyof typeof types;
if (!type) {
throw new Error("Type is missing from JSON");
}
if (!types[type]) {
throw new Error(`Type ${type} is not supported`);
}
const model = new types[type]();
for (const key in json) {
// Infer key type from model
if (typeof json[key] === "object" && json[key].hasOwnProperty("type")) {
// @ts-ignore
model[key] = Model.fromJson(json[key]);
continue;
}
if (
Array.isArray(json[key]) &&
json[key].length > 0 &&
json[key][0].hasOwnProperty("type")
) {
// @ts-ignore
model[key] = json[key].map((item: any) => Model.fromJson(item));
continue;
}
// @ts-ignore
model[key] = json[key];
}
return model as Value;
}
}
export class Profile {
id: number;
avatar: string;
constructor() {
this.id = 0;
this.avatar = "";
}
}
import { Model } from "./model";
const users = Model.fromJson([
{
id: 1,
name: "John Doe",
type: "user",
},
{
id: 2,
name: "Jane Doe",
type: "user",
},
]);
const user = Model.fromJson({
id: 1,
name: "John Doe",
type: "user",
});
console.log(user.profile?.id);
console.log(users[0].profile?.id);
import { Profile } from "./profile";
export class User {
id: number;
name: string;
email: string;
phone: string;
address: string;
city: string;
state: string;
zip: string;
country: string;
image: string;
profile?: Profile;
constructor() {
this.id = 0;
this.name = "";
this.email = "";
this.phone = "";
this.address = "";
this.city = "";
this.state = "";
this.zip = "";
this.country = "";
this.image = "";
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment