Created
March 13, 2021 13:50
-
-
Save kana-sama/2308d78d98836f202a4b64f810ca40da 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 ok<value, rest> = [value, rest]; | |
type fail = []; | |
type fix_intersection<a> = { [key in keyof a]: a[key] } | |
type parse_substring<sub extends string, s1> = | |
s1 extends `${sub}${infer s2}` ? | |
ok<null, s2> : fail; | |
type space = " " | "\n"; | |
type parse_space<s1> = | |
s1 extends `${space}${infer s2}` ? parse_space<s2> : ok<null, s1>; | |
type parse_name<s1> = | |
s1 extends `${infer name}:${infer s2}` ? | |
ok<name, `:${s2}`> : fail; | |
type prims = { | |
number: number, | |
string: string, | |
boolean: boolean, | |
}; | |
type parse_type<s1> = | |
s1 extends `${keyof prims}${infer s2}` ? | |
s1 extends `${infer type_}${s2}` ? ok<prims[type_ & keyof prims], s2> : fail : | |
parse_record<s1>; | |
type parse_field<s1> = | |
parse_name<s1> extends ok<infer name, infer s2> ? | |
name extends string ? | |
parse_substring<": ", s2> extends ok<null, infer s3> ? | |
parse_type<s3> extends ok<infer type_, infer s4> ? | |
ok<{[k in name]: type_}, s4> : fail : fail : fail : fail; | |
type parse_fields<s1> = | |
parse_field<s1> extends ok<infer field, infer s2> | |
? parse_substring<",", s2> extends ok<null, infer s3> ? | |
parse_space<s3> extends ok<null, infer s4> ? | |
parse_fields<s4> extends ok<infer fields, infer s5> ? | |
ok<fix_intersection<field & fields>, s5> : fail : fail : ok<field, s2> | |
: ok<{}, s1> | |
type parse_record<s1> = | |
parse_substring<"{", s1> extends ok<null, infer s2> ? | |
parse_space<s2> extends ok<null, infer s3> ? | |
parse_fields<s3> extends ok<infer fields, infer s4> ? | |
parse_space<s4> extends ok<null, infer s5> ? | |
parse_substring<"}", s5> extends ok<null, infer s6> ? | |
ok<fields, s6> : fail : fail : fail : fail : fail; | |
type run<result> = result extends ok<infer value, ""> ? value : never; | |
const asrc = `{ | |
a: number, e: boolean, | |
b: { c: string, d: string } | |
}`; | |
type a = run<parse_record<typeof asrc>>; | |
const a: a = { e: true, a: 1, b: { c: "hello", d: "world" } }; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment