Type-Function to Parse JSON into TypeScript types
This file contains 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 Whitespace = " " | "\n" | "\r" | "\t"; | |
type TrimStart<T extends string> = T extends `${Whitespace}${infer R}` ? TrimStart<R> : T; | |
type TrimEnd<T extends string> = T extends `${infer R}${Whitespace}` ? TrimEnd<R> : T; | |
type Trim<T extends string> = TrimStart<TrimEnd<T>>; | |
type BoolLiteral = "true" | "false"; | |
type Digit = "0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9"; | |
type InferJsonScalarType<T extends string> = Trim<T> extends `"${infer _}"` ? string | |
: Trim<T> extends `${BoolLiteral}` ? boolean | |
: Trim<T> extends `${Digit}${infer _}` ? number | |
: Trim<T> extends `null` ? null | |
: never; | |
type HeadingJsonScalar<T extends string> = Trim<T> extends `"${infer Str}",${infer _}` ? `"${Str}"` | |
: Trim<T> extends `${infer Token},${infer _}` ? Token | |
: T; | |
type TrailingJsonEntries<T extends string> = Trim<T> extends `"${infer _}",${infer Tail}` ? Tail | |
: Trim<T> extends `${infer _},${infer Tail}` ? Tail | |
: T; | |
type DecodeJsonStr<T extends string> = T extends `"${infer R}"` ? R : never; | |
type InfoerJsonObjectEntries<T extends string> = Trim<T> extends `${infer K}:${infer Tail}` | |
? { [key in DecodeJsonStr<Trim<K>>]: InferJsonScalarType<HeadingJsonScalar<Tail>> } & InfoerJsonObjectEntries<TrailingJsonEntries<Tail>> | |
: {}; | |
export type TypeFromJson<T extends string> = Trim<T> extends `{${infer InnerJsonObject}}` | |
? InfoerJsonObjectEntries<InnerJsonObject> | |
: never; | |
const json = ` | |
{ | |
"name": "foo", | |
"answer": 42, | |
"ok": true | |
} | |
`; | |
type ResultType = TypeFromJson<typeof json>; | |
// ResultType is almost { name: string; answer: number; ok: boolean } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment