-
-
Notifications
You must be signed in to change notification settings - Fork 98
Expand file tree
/
Copy pathnormal.ts
More file actions
122 lines (106 loc) · 3.88 KB
/
normal.ts
File metadata and controls
122 lines (106 loc) · 3.88 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
111
112
113
114
115
116
117
118
119
120
121
122
import type {
Schema,
Serializable,
EntityInterface,
NormalizedIndex,
} from './interface.js';
export * from './schemaArgs.js';
// TypeScript <4.2 InstanceType<> does not work on abstract classes
export type AbstractInstanceType<T> =
T extends new (...args: any) => infer U ? U
: T extends { prototype: infer U } ? U
: never;
export type NormalizedEntity<T> =
T extends (
{
prototype: infer U;
schema: infer S;
}
) ?
{ [K in Exclude<keyof U, keyof S>]: U[K] } & { [K in keyof S]: string }
: never;
export type DenormalizeObject<S extends Record<string, any>> = {
[K in keyof S]: S[K] extends Schema ? Denormalize<S[K]> : S[K];
};
export type DenormalizeNullableObject<S extends Record<string, any>> = {
[K in keyof S]: S[K] extends Schema ? DenormalizeNullable<S[K]> : S[K];
};
export type NormalizeObject<S extends Record<string, any>> = {
[K in keyof S]: S[K] extends Schema ? Normalize<S[K]> : S[K];
};
export type NormalizedNullableObject<S extends Record<string, any>> = {
[K in keyof S]: S[K] extends Schema ? NormalizeNullable<S[K]> : S[K];
};
interface NestedSchemaClass<T = any> {
schema: Record<string, Schema>;
prototype: T;
}
export interface RecordClass<T = any> extends NestedSchemaClass<T> {
fromJS: (...args: any) => AbstractInstanceType<T>;
}
export type DenormalizeNullableNestedSchema<S extends NestedSchemaClass> =
keyof S['schema'] extends never ?
S['prototype'] // this is the case of a non-set schema, which means it actually has no members
: string extends keyof S['schema'] ? S['prototype']
: S['prototype'] & {
[K in keyof S['schema']]: DenormalizeNullable<S['schema'][K]>;
};
export type NormalizeReturnType<T> =
T extends (...args: any) => infer R ? R : never;
export type Denormalize<S> =
S extends { createIfValid: any; pk: any; key: string; prototype: infer U } ? U
: S extends RecordClass ? AbstractInstanceType<S>
: S extends { denormalize: (...args: any) => any } ?
ReturnType<S['denormalize']>
: S extends Serializable<infer T> ? T
: S extends Array<infer F> ? Denormalize<F>[]
: S extends { [K: string]: any } ? DenormalizeObject<S>
: S;
export type DenormalizeNullable<S> =
S extends (
{ createIfValid: any; pk: any; key: string; prototype: any; schema: any }
) ?
DenormalizeNullableNestedSchema<S> | undefined
: S extends RecordClass ? DenormalizeNullableNestedSchema<S>
: S extends { _denormalizeNullable: (...args: any) => any } ?
ReturnType<S['_denormalizeNullable']>
: S extends Serializable<infer T> ? T
: S extends Array<infer F> ? Denormalize<F>[] | undefined
: S extends { [K: string]: any } ? DenormalizeNullableObject<S>
: S;
export type Normalize<S> =
S extends { createIfValid: any; pk: any; key: string; prototype: {} } ? string
: S extends RecordClass ? NormalizeObject<S['schema']>
: S extends { normalize: (...args: any) => any } ?
NormalizeReturnType<S['normalize']>
: S extends Serializable<infer T> ? T
: S extends Array<infer F> ? Normalize<F>[]
: S extends { [K: string]: any } ? NormalizeObject<S>
: S;
export type NormalizeNullable<S> =
S extends { createIfValid: any; pk: any; key: string; prototype: {} } ?
string | undefined
: S extends RecordClass ? NormalizedNullableObject<S['schema']>
: S extends { _normalizeNullable: (...args: any) => any } ?
NormalizeReturnType<S['_normalizeNullable']>
: S extends Serializable<infer T> ? T
: S extends Array<infer F> ? Normalize<F>[] | undefined
: S extends { [K: string]: any } ? NormalizedNullableObject<S>
: S;
export type NormalizedSchema<E, R> = {
entities: E;
result: R;
indexes: NormalizedIndex;
entitiesMeta: {
readonly [entityKey: string]: {
readonly [pk: string]: {
readonly date: number;
readonly expiresAt: number;
readonly fetchedAt: number;
};
};
};
};
export interface EntityMap<T = any> {
readonly [k: string]: any;
}