-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
mod.ts
82 lines (65 loc) · 3.26 KB
/
mod.ts
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
/*! (c) 2022 TANIGUCHI Masaya. https://git.io/mit-license */
type StringifyArgs = Parameters<typeof JSON.stringify>
type ParseArgs = Parameters<typeof JSON.parse>
export class JSONUP {
static parse<T extends string>(string: T, reviver?: ParseArgs[1]): ObjectLike<T> {
return JSON.parse(string, reviver)
}
static stringify<T extends string>(object: ObjectLike<T>, replacer?: StringifyArgs[1], space?: StringifyArgs[2]): T {
return JSON.stringify(object, replacer, space) as T
}
}
export type ObjectLike<T> = JsonValue<T> extends [infer L, ''] ? L : never
type Trim<T> =
T extends `${' ' | ' \t' | '\n' | '\r'}${infer S}` ? Trim<S> :
T extends `${infer S}${' ' | ' \t' | '\n' | '\r'}` ? Trim<S> : T;
type JsonValue<T> =
JsonStringValue<T> | JsonNumber<T> | JsonNull<T> | JsonBoolean<T> | JsonArray<T> | JsonObject<T>
type JsonStringKeyInner<T, U extends string> =
Trim<T> extends `\\"${infer S}` ? JsonStringKeyInner<S, `${U}"`> :
Trim<T> extends `"${infer S}` ? [U, Trim<S>] :
Trim<T> extends `${infer L}${infer R}` ? JsonStringKeyInner<R, `${U}${L}`> :
never;
type JsonStringKey<T> =
Trim<T> extends `"${infer S}` ? JsonStringKeyInner<S, ''> : never;
type JsonStringValueInner<T, U extends string> =
Trim<T> extends `\\"${infer S}` ? JsonStringValueInner<S, `${U}"`> :
Trim<T> extends `"${infer S}` ? [string, Trim<S>] :
Trim<T> extends `${infer L}${infer R}` ? JsonStringValueInner<R, `${U}${L}`> :
never;
type JsonStringValue<T> =
Trim<T> extends `"${infer S}` ? JsonStringValueInner<S, ''> : never;
type JsonNumber<T> =
Trim<T> extends `${number}` ? [number, ''] :
Trim<T> extends `${number}]${infer R}` ? [number, Trim<`]${R}`>] :
Trim<T> extends `${number}}${infer R}` ? [number, Trim<`}${R}`>] :
Trim<T> extends `${number},${infer R}` ? [number, Trim<`,${R}`>] :
never;
type JsonNull<T> =
Trim<T> extends `${null}` ? [null, ''] :
Trim<T> extends `${null}]${infer R}` ? [null, Trim<`]${R}`>] :
Trim<T> extends `${null}}${infer R}` ? [null, Trim<`}${R}`>] :
Trim<T> extends `${null},${infer R}` ? [null, Trim<`,${R}`>] :
never;
type JsonBoolean<T> =
Trim<T> extends `${boolean}` ? [boolean, ''] :
Trim<T> extends `${boolean}]${infer R}` ? [boolean, Trim<`]${R}`>] :
Trim<T> extends `${boolean}}${infer R}` ? [boolean, Trim<`}${R}`>] :
Trim<T> extends `${boolean},${infer R}` ? [boolean, Trim<`,${R}`>] :
never;
type JsonArrayInner<T, L> =
JsonValue<T> extends [infer V, `,${infer R}`] ? JsonArrayInner<R, V | L> :
JsonValue<T> extends [infer V, `]${infer R}`] ? [(V | L)[], Trim<R>] : never;
type JsonArray<T> =
Trim<T> extends `[]${infer R}` ? [[], Trim<R>] :
Trim<T> extends `[${infer S}` ? JsonArrayInner<S, never> : never;
type JsonKeyValue<T> =
JsonStringKey<T> extends [infer K extends string, `:${infer R}`] ?
(JsonValue<R> extends [infer V, infer Q] ? [{[_ in K]: V}, Trim<Q>] : never) : never
type Flatten<T> = T extends Record<string, unknown> ? { [k in keyof T] : T[k] } : never
type JsonObjectInner<T, L> =
JsonKeyValue<T> extends [infer KV, `,${infer R}`] ? JsonObjectInner<R, L & KV> :
JsonKeyValue<T> extends [infer KV, `}${infer R}`] ? [Flatten<L & KV>, Trim<R>] : never;
type JsonObject<T> =
Trim<T> extends `{}${infer R}` ? [{}, Trim<R>] :
Trim<T> extends `{${infer S}` ? JsonObjectInner<S, {}> : never;