Type Challenges Judge

JSON Parser

提出詳細

type Pure<T> = { [P in keyof T]: T[P] extends object ? Pure<T[P]> : T[P] } type SetProperty<T, K extends PropertyKey, V> = { [P in (keyof T) | K]: P extends K ? V : P extends keyof T ? T[P] : never } type Token = | { kind: "objS" } | { kind: "objE" } | { kind: "arrS" } | { kind: "arrE" } | { kind: "comma" } | { kind: "colon" } | { kind: "str", value: string } | { kind: "true" } | { kind: "false" } | { kind: "null" } type ParseResult<T, K extends Token[]> = [T, K] type Take<S extends string> = S extends `${infer head}${infer rest}` ? [head, rest] : ["", ""] type Unescape<S extends string, res extends string = ""> = S extends "" ? res : S extends `\\b${infer R}` ? Unescape<R, `${res}\b`> : S extends `\\f${infer R}` ? Unescape<R, `${res}\f`> : S extends `\\n${infer R}` ? Unescape<R, `${res}\n`> : S extends `\\r${infer R}` ? Unescape<R, `${res}\r`> : S extends `\\t${infer R}` ? Unescape<R, `${res}\t`> : Take<S> extends [infer Char extends string, infer R extends string] ? Unescape<R, `${res}${Char}`> : "" // unreachable type Tokenize<S extends string, T extends Token[] = []> = Take<S> extends [infer Char, infer R extends string] ? Char extends "" ? T : Char extends " " | "\n" | "\r" | "\t" ? Tokenize<R, T> : Char extends `{` ? Tokenize<R, [...T, { kind: "objS" }]> : Char extends `}` ? Tokenize<R, [...T, { kind: "objE" }]> : Char extends `[` ? Tokenize<R, [...T, { kind: "arrS" }]> : Char extends `]` ? Tokenize<R, [...T, { kind: "arrE" }]> : Char extends `:` ? Tokenize<R, [...T, { kind: "colon" }]> : Char extends `,` ? Tokenize<R, [...T, { kind: "comma" }]> : S extends `true${infer RR}` ? Tokenize<RR, [...T, { kind: "true" }]> : S extends `false${infer RR}` ? Tokenize<RR, [...T, { kind: "false" }]> : S extends `null${infer RR}` ? Tokenize<RR, [...T, { kind: "null" }]> : S extends `"${infer s}"${infer RR}` ? Tokenize<RR, [...T, { kind: "str", value: Unescape<s> }]> : [] : [] type TestTokenizeObj = Expect<Equal< Tokenize<'{"aa": true,"cc": "foo"}'>, [ { kind: "objS" }, { kind: "str", value: "aa" }, { kind: "colon" }, { kind: "true" }, { kind: "comma" }, { kind: "str", value: "cc" }, { kind: "colon" }, { kind: "str", value: "foo" }, { kind: "objE" }, ] >> type TestTokenizeArr = Expect<Equal<Tokenize<'["Hello", true, false, null]'>, [{ kind: "arrS" }, { kind: "str", value: "Hello" }, { kind: "comma" }, { kind: "true" }, { kind: "comma" }, { kind: "false" }, { kind: "comma" }, { kind: "null" }, { kind: "arrE" }] >> type ParseLiteral<T extends Token[]> = T extends [infer Cur extends Token, ...infer R extends Token[]] ? Cur extends { kind: "objS" } ? ParseObject<T> : Cur extends { kind: "arrS" } ? ParseArray<T> : Cur extends { kind: "str" } ? [Cur["value"], R] : Cur extends { kind: "true" } ? [true, R] : Cur extends { kind: "false" } ? [false, R] : Cur extends { kind: "null" } ? [null, R] : [never, T] : [never, T] /** consume * "foo": true, * "bar": false */ type ParsePair<T extends Token[], result extends object = {}> = T extends [infer K extends { kind: "str", value: string }, { kind: "colon" }, ...infer R extends Token[]] ? ParseLiteral<R> extends [infer V, infer Tail extends Token[]] ? Tail extends [{ kind: "objE" }, ...unknown[]] ? [SetProperty<result, K["value"], V>, Tail] : Tail extends [{ kind: "comma" }, ...infer Next extends Token[]] ? ParsePair<Next, SetProperty<result, K["value"], V>> : [never, Tail] : never : T[0] extends { kind: "objE" } ? [{}, T] : [never, T] type TestPair = Expect<Equal<ParsePair<[ { kind: "str", value: "aa" }, { kind: "colon" }, { kind: "true" }, { kind: "comma" }, { kind: "str", value: "bb" }, { kind: "colon" }, { kind: "false" }, { kind: "comma" }, { kind: "str", value: "cc" }, { kind: "colon" }, { kind: "str", value: "foo" }, { kind: "objE" } ]>, [{ aa: true, bb: false, cc: "foo" }, [{ kind: "objE" }]]>> type ParseObject<T extends Token[]> = T extends [{ kind: "objS" }, ...infer R extends Token[]] ? ParsePair<R> extends [infer kv, infer RR extends Token[]] ? RR extends [{ kind: "objE" }, ...infer RRR extends Token[]] ? [kv, RRR] : [never, RR] : never : [never, T] type TestObj = Expect<Equal< ParseObject<Tokenize<`{"aa": true,"bb": false,"cc": "foo"}`>>, [{ "aa": true, "bb": false, "cc": "foo" }, []]>> type TestObj2 = ParseObject<Tokenize<`{"aa": true,"bb": false,"cc": "foo"}`>> type ParseArray<T extends Token[], result extends unknown[] = []> = T extends [infer Cur extends Token, ...infer R extends Token[]] ? Cur extends { kind: "arrS" } ? result["length"] extends 0 ? ParseArray<R> : [never, R] : Cur extends { kind: "arrE" } ? [result, R] : Cur extends { kind: "comma" } ? ParseArray<R, result> : Cur extends { kind: "str" | "true" | "false" | "null" | "objS" | "arrS" } ? ParseLiteral<T> extends [infer V, infer RToken extends Token[]] ? ParseArray<RToken, [...result, V]> : [never, R] : [never, R] : [never, T] type TestArr = Expect<Equal< ParseArray<[ { kind: "arrS" }, { kind: "str", value: "foo" }, { kind: "comma" }, { kind: "str", value: "bar" }, { kind: "true" }, { kind: "comma" }, { kind: "false" }, { kind: "arrE" }, ]>, [["foo", "bar", true, false], []] >> type Parse<T extends string> = Pure<ParseLiteral<Tokenize<T>>[0]>
提出日時2026-03-22 16:47:42
問題JSON Parser
ユーザーookkoouu
ステータスAccepted
テストケース
import type { Equal, Expect } from '@type-challenges/utils' type cases = [ Expect<Equal<( Parse<` { "a": "b", "b": false, "c": [true, false, "hello", { "a": "b", "b": false }], "nil": null } `> ), ( { nil: null c: [true, false, 'hello', { a: 'b' b: false }] b: false a: 'b' } )>>, Expect<Equal<Parse<'{}'>, {}>>, Expect<Equal<Parse<'[]'>, []>>, Expect<Equal<Parse<'[1]'>, never>>, Expect<Equal<Parse<'true'>, true>>, Expect<Equal< Parse<'["Hello", true, false, null]'>, ['Hello', true, false, null] >>, Expect<Equal< ( Parse<` { "hello\\r\\n\\b\\f": "world" }`> ), ( { 'hello\r\n\b\f': 'world' } ) >>, Expect<Equal<Parse<'{ 1: "world" }'>, never>>, Expect<Equal<Parse<`{ "hello world": 123 }`>, never>>, ]