Created
February 24, 2026 13:46
-
-
Save Nyrox/4ea32e8b3de0aaa5e214511869ab2289 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| type Serializer<From, To> = { | |
| serialize: (v: From) => To; | |
| deserialize: (v: To) => From; | |
| }; | |
| const DateSerializer: Serializer<Date, number> = { | |
| serialize: (d) => d.getTime(), | |
| deserialize: (n) => new Date(n), | |
| }; | |
| type DeepWriteable<T> = T extends object ? { -readonly [P in keyof T]: DeepWriteable<T[P]> } : T; | |
| type Fail<Message extends string> = { | |
| __message__: Message; | |
| }; | |
| type UnFail<T> = | |
| T extends Fail<string> ? never : T extends object ? { [K in keyof T]: UnFail<T[K]> } : T; | |
| type ToTypeString<T, Fallback extends string> = T extends string | number | boolean | |
| ? T | |
| : T extends Date | |
| ? 'Date' | |
| : Fallback; | |
| type NoExtraKeys<Candidate, Target> = | |
| Exclude<keyof Candidate, keyof Target> extends never | |
| ? true | |
| : Fail<`Serializer contains keys not present in target type.`> & { | |
| extraKeys: ToTypeString<Exclude<keyof Candidate, keyof Target>, 'unknown'>; | |
| }; | |
| type Assert<Cond extends true | Fail<string>, T> = Cond extends true ? T : Cond; | |
| type ApplySerializer<S extends Record<string, unknown>, T extends Record<string, unknown>> = Assert< | |
| NoExtraKeys<S, T>, | |
| { | |
| [K in keyof T]: S extends { [SK in K]: object } | |
| ? S[K] extends Serializer<T[K], infer To> | |
| ? To | |
| : S[K] extends Serializer<infer From, infer To> | |
| ? Fail<`Serializers contains serializer '${ToTypeString<K, 'K'>}' :: '${ToTypeString<From, 'From'>}' -> '${ToTypeString<To, 'To'>}', but corresponding type in target type is '${ToTypeString<T[K], 'incompatible'>}'`> | |
| : S[K] extends Record<string, object> | |
| ? T[K] extends Record<string, unknown> | |
| ? ApplySerializer<S[K], T[K]> | |
| : Fail<`Serializers contains nested serializer '${ToTypeString<K, 'K'>}', but corresponding target type '${ToTypeString<T[K], 'unknown'>}' is not an object.`> | |
| : Fail<`Serializers contains key '${ToTypeString<K, 'K'>}' which is not a valid serializer or record.`> | |
| : T[K]; | |
| } | |
| >; | |
| /** | |
| * ^ | |
| * | | |
| * | | |
| * | DANGER | |
| * | |
| * | |
| * | |
| * THE WALL WHICH PROTECTS US | |
| * | |
| */ | |
| const DocumentSerializer = { | |
| createdAt: DateSerializer, | |
| nested: { | |
| createdAt: {} as Serializer<string, number>, | |
| }, | |
| } as const; | |
| type SerializedDocument = ApplySerializer< | |
| typeof DocumentSerializer, | |
| Document | |
| >; | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment