-
-
Notifications
You must be signed in to change notification settings - Fork 4.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
JSON Stringifier #22394
Labels
new-challenge
Propose a new challenge, a PR will be auto generated
Comments
hydrati
added
the
new-challenge
Propose a new challenge, a PR will be auto generated
label
Jan 19, 2023
#22395 - Pull Request updated. |
Possible solution: /* Imported from '@type-challenges/utils' */
// type Equal<X, Y> = (<T>() => T extends X ? 1 : 2) extends (<T>() => T extends Y ? 1 : 2) ? true : false
type Escape = {
"\"": '\\"',
"\\": '\\\\',
"\/": '\\/',
'\b': '\\b',
'\f': '\\f',
'\n': '\\n',
'\r': '\\r',
'\t': '\\t'
}
type StringifyPrimitive<T> =
Equal<T, true> extends true
? 'true'
: Equal<T, false> extends true
? 'false'
: Equal<T, null> extends true
? `null`
: T extends string
? [EscapeString<T>] extends [never]
? never
: `"${EscapeString<T>}"`
: never
type EscapeString<T extends string, Output extends string = ''> =
string extends T
? never
: T extends ''
? Output
: T extends `${infer P}${infer R}`
? EscapeString<R, `${Output}${P extends keyof Escape ? Escape[P] : P}`>
: never
type StringifyArrayElement<T extends unknown[], Output extends string = ''> =
T extends [infer P, ...infer R]
? StringifyArrayElement<R, `${Output}${Output extends '' ? '' : ','}${Stringify<P>}`>
: T extends []
? Output
: never
type StringifyArray<T extends unknown> =
T extends unknown[]
? number extends T['length']
? never
: `[${StringifyArrayElement<T>}]`
: never
type StringifyObject<T extends unknown> =
T extends Record<string, unknown>
? Record<string, unknown> extends T
? Equal<T, {}> extends true
? `{}`
: never
: `{${StringifyObjectEntries<T>}}`
: never
type UnionIntersectionFn<T> =
(T extends T ? (x: () => T) => never : never) extends ((x: infer P) => never)
? P
: never
type UnionLast<T> = UnionIntersectionFn<T> extends () => infer P ? P : never
type StringifyObjectEntries<T extends Record<string, unknown>, Output extends string = ''> =
[keyof T] extends [never]
? Output
: UnionLast<keyof T> extends infer Key extends string
? StringifyObjectEntries<{ [P in Exclude<keyof T, Key>]: T[P] }, `${Output}${Output extends '' ? '' : ','}${StringifyPrimitive<Key>}:${Stringify<T[Key]>}`>
: never
type Stringify<T extends unknown> =
| StringifyArray<T>
| StringifyPrimitive<T>
| StringifyObject<T> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Info
Basic info of your challenge questions,
Question
You're required to implement a type-level partly stringifier to stringify a literal type into a JSON string.
Requirements:
Numbers (number, bigint)
,Symbol (symbol)
,Unicode escape (\uxxxx)
,undefined
in the input can be ignored. You needn't to stringify them.Template
This is the template for challengers to start the coding. Basically, you just need to change the name of your generic/function and leave to implementation
any
.Test Cases
Provide some test cases for your challenge, you can use some utils from
@type-challenges/utils
for asserting.The text was updated successfully, but these errors were encountered: