Created
November 19, 2024 07:16
-
-
Save WomB0ComB0/074085301c54fd3cec2090de4f17bd3a to your computer and use it in GitHub Desktop.
Build-time Typescript-Type-safe JSON parser
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
// Base utility types | |
type Whitespace = '\u{9}' | '\u{A}' | '\u{20}' // tab, newline, space | |
type TrimLeft<V extends string> = V extends `${Whitespace}${infer R}` | |
? TrimLeft<R> | |
: V | |
type TrimRight<V extends string> = V extends `${infer R}${Whitespace}` | |
? TrimRight<R> | |
: V | |
type Trim<V extends string> = TrimLeft<TrimRight<V>> | |
type Prettify<T> = { | |
[K in keyof T]: T[K] | |
} & {} | |
// Type detection helpers | |
type IsDate<T> = T extends string | |
? T extends `${number}${number}${number}${number}-${number}${number}-${number}${number}` | |
? true | |
: false | |
: false | |
type IsNumeric<T> = T extends number | |
? true | |
: T extends `${number}` | |
? true | |
: false | |
// Custom type handling | |
type CustomTypes = Record<string, string | Record<string, unknown>> | |
type Scalar = Record<string, unknown> | |
// Main type extractor | |
type ExtractType<T> = T extends Array<infer U> | |
? ExtractType<U>[] | |
: T extends object | |
? { | |
[K in keyof T]: T[K] extends string | |
? IsDate<T[K]> extends true | |
? Date | |
: IsNumeric<T[K]> extends true | |
? number | |
: string | |
: ExtractType<T[K]> | |
} | |
: T extends string | |
? IsDate<T> extends true | |
? Date | |
: IsNumeric<T> extends true | |
? number | |
: string | |
: T extends number | |
? number | |
: T extends boolean | |
? boolean | |
: T extends null | |
? null | |
: T extends undefined | |
? undefined | |
: never | |
// String parsing type | |
type ExtractTypeFromString<T extends string> = T extends `${infer Type}\n${infer Rest}` | |
? [TrimLeft<Type>, Rest] | |
: T extends `${infer Type} ${infer Rest}` | |
? [TrimLeft<Type>, Rest] | |
: never | |
// Usage helper type | |
type InferredType<T> = Prettify<ExtractType<T>> | |
// Example usage: | |
const processData = <T>(data: T): InferredType<T> => { | |
return data as InferredType<T>; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment