-
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuser-classes.ts
More file actions
110 lines (102 loc) · 3.06 KB
/
user-classes.ts
File metadata and controls
110 lines (102 loc) · 3.06 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
import {
ProtoObject,
StaticImplements,
ProtoObjectStaticMethods,
protoObjectFactory,
} from "protoobject";
// Example using interface and factory pattern
interface IUserRights extends ProtoObject<IUserRights> {
isAdmin: boolean;
updatedAt: Date;
}
/**
* Example of creating a class using factory pattern with TypeScript
* This approach provides type safety and interface compliance
*/
export const UserRights = protoObjectFactory<IUserRights>({
fromJSON(data) {
return new this({
...ProtoObject.fromJSON(data),
updatedAt: new Date(data?.updatedAt),
});
},
toJSON() {
return {
...UserRights?.prototype?.toJSON?.call(this),
updatedAt: this.updatedAt?.toJSON(),
};
},
});
/**
* Example of creating a simple ProtoObject heir with TypeScript decorators
* The decorator ensures static method compliance at compile time
*/
@StaticImplements<ProtoObjectStaticMethods<UserAddress>>()
export class UserAddress extends ProtoObject<UserAddress> {
constructor(data?: Partial<UserAddress>) {
super(data);
// Note: assign data after calling super() to ensure proper field initialization
if (data) this.assign(data);
return this;
}
country!: string;
postCode!: string;
}
/**
* Example of creating a complex ProtoObject heir with TypeScript
* Includes full type safety, decorators, and custom serialization
*/
@StaticImplements<ProtoObjectStaticMethods<User>>()
export class User extends ProtoObject<User> {
constructor(data?: Partial<User>) {
super(data);
// Note: assign data after calling super() to ensure proper field initialization
if (data) this.assign(data);
return this;
}
id!: string;
email!: string;
createdAt!: Date;
photo?: Buffer;
address?: UserAddress;
rights?: IUserRights;
/**
* Custom JSON serialization for complex types
* Standard types (String, Number, Boolean) are handled automatically
*/
public toJSON(): { [key: string]: any } {
return {
...super.toJSON.call(this),
createdAt: this.createdAt.toJSON(),
photo:
this.photo instanceof Buffer ? this.photo.toString("hex") : undefined,
address:
this.address instanceof UserAddress ? this.address.toJSON() : undefined,
rights:
this.rights instanceof UserRights ? this.rights?.toJSON() : undefined,
};
}
/**
* Custom JSON deserialization for complex types
* Standard types (String, Number, Boolean) are handled automatically
*/
public static fromJSON<User>(data: { [key: string]: unknown }): User {
return new User({
...super.fromJSON(data),
createdAt:
typeof data.createdAt === "string"
? new Date(data.createdAt)
: undefined,
photo:
typeof data.photo === "string"
? Buffer.from(data.photo, "hex")
: undefined,
address: data.address
? UserAddress.fromJSON<UserAddress>(
data.address as { [key: string]: unknown }
)
: undefined,
rights: data.rights ? UserRights.fromJSON(data.rights) : undefined,
}) as unknown as User;
}
}