-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
parse-json.d.ts
61 lines (53 loc) · 2.28 KB
/
parse-json.d.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
export type ParseJson<Json extends string> =
ParseJson.ParseValue<ParseJson.TrimLeft<Json>> extends
[infer Parsed, infer Tail extends string] ? [Parsed] extends [never] ? never
: ParseJson.TrimLeft<Tail> extends "" ? Parsed
: never
: never;
declare namespace ParseJson {
type TrimLeft<Json extends string> = Json extends
`${" " | "\n" | "\t"}${infer R}` ? TrimLeft<R>
: Json;
type ParseValue<Json extends string> = Json extends `undefined${infer R}`
? [undefined, TrimLeft<R>]
: Json extends `null${infer R}` ? [null, TrimLeft<R>]
: Json extends `true${infer R}` ? [true, TrimLeft<R>]
: Json extends `false${infer R}` ? [false, TrimLeft<R>]
: Json extends `"${infer Str}"${infer R}` ? [ParseString<Str>, TrimLeft<R>]
: Json extends `[${infer R}`
? TrimLeft<R> extends `]${infer R}` ? [[], TrimLeft<R>]
: ParseArray<`,${TrimLeft<R>}`>
: Json extends `{${infer R}`
? TrimLeft<R> extends `}${infer R}` ? [{}, TrimLeft<R>]
: ParseObject<`,${TrimLeft<R>}`>
: never;
type ParseString<S extends string> = S extends
`${infer L}\\${infer C extends keyof EscChars}${infer R}`
? ParseString<`${L}${EscChars[C]}${R}`>
: S;
type EscChars = { n: "\n"; t: "\t"; r: "\r"; b: "\b"; f: "\f" };
type ParseArray<Json extends string, Arr extends any[] = []> = Json extends
`]${infer R}` ? [Arr, TrimLeft<R>]
: Json extends `,${infer R}`
? ParseValue<TrimLeft<R>> extends [infer Value, infer R extends string]
? [Value] extends [never] ? never
: ParseArray<TrimLeft<R>, [...Arr, Value]>
: never
: never;
type ParseObject<Json extends string, Obj extends object = {}> = Json extends
`}${infer R}` ? [Merge<Obj>, TrimLeft<R>]
: Json extends `,${infer R}`
? ParseKey<TrimLeft<R>> extends [infer Key extends string, infer R]
? R extends `:${infer R}`
? ParseValue<TrimLeft<R>> extends
[infer Value, infer R extends string]
? ParseObject<TrimLeft<R>, Obj & { [K in Key]: Value }>
: never
: never
: never
: never;
type ParseKey<Json extends string> = Json extends `"${infer Key}"${infer R}`
? [ParseString<Key>, TrimLeft<R>]
: never;
type Merge<T> = T extends object ? { [K in keyof T]: Merge<T[K]>; } : T;
}