Implement the generic type JSONSchema2TS which will return the TypeScript type corresponding to the given JSON schema. Master advanced TypeScript type manipulation in this medium-level challenge on TypeScriptPro.
In this medium-level challenge, you'll implement the generic type JSONSchema2TS which converts a JSON Schema definition into its corresponding TypeScript type, handling primitives, enums, objects with required/optional properties, and arrays.
Implement the generic type JSONSchema2TS which will return the TypeScript type corresponding to the given JSON schema.
Additional challenges to handle: additionalProperties oneOf, anyOf, allOf minLength and maxLength
Change the following code to make the test cases pass (no type check errors).
// + Primitive types
type Type1 = JSONSchema2TS<{
type: 'string'
}>
type Expected1 = string
type Result1 = Expect<Equal<Type1, Expected1>>
type Type2 = JSONSchema2TS<{
type: 'number'
}>
type Expected2 = number
type Result2 = Expect<Equal<Type2, Expected2>>
type Type3 = JSONSchema2TS<{
type: 'boolean'
}>
type Expected3 = boolean
type Result3 = Expect<Equal<Type3, Expected3>>
// - Primitive types
// + Enums
type Type4 = JSONSchema2TS<{
type: 'string'
enum: ['a', 'b', 'c']
}>
type Expected4 = 'a' | 'b' | 'c'
type Result4 = Expect<Equal<Type4, Expected4>>
type Type5 = JSONSchema2TS<{Unlock 102+ medium, hard, and extreme challenges to master advanced TypeScript.
One-time payment. Lifetime access.
type JSONSchema2TS<T> =
T extends { type: 'string'; enum: infer E extends string[] }
? E[number]
: T extends { type: 'number'; enum: infer E extends number[] }
? E[number]
: T extends { type: 'string' }
? string
: T extends { type: 'number' }
? number
: T extends { type: 'boolean' }
? boolean
: T extends { type: 'object'; properties: infer P; required: infer R extends string[] }
? {
[K in keyof P as K extends R[number] ? K : never]: JSONSchema2TS<P[K]>
} & {
[K in keyof P as K extends R[number] ? never : K]?: JSONSchema2TS<P[K]>
} extends infer O
? { [K in keyof O]: O[K] }
: never
: T extends { type: 'object'; properties: infer P }
? { [K in keyof P]?: JSONSchema2TS<P[K]> }
: T extends { type: 'object' }
? Record<string, unknown>
: T extends { type: 'array'; items: infer I }
? JSONSchema2TS<I>[]
: T extends { type: 'array' }
? unknown[]
: never;How it works:
type field of the JSON schema objectstring, number, boolean), it returns the corresponding TypeScript primitive type directlyenum array is present alongside a primitive type, it extracts the union of literal values using E[number] instead of returning the broad primitiveobject types with properties and a required array, it splits properties into two mapped types: required keys (without ?) and optional keys (with ?), then flattens them with an intersectionobject types with properties but no required field, all properties default to optionalobject type with no properties returns Record<string, unknown>array types, it recursively resolves the items schema and wraps the result in an array; a bare array type returns unknown[]This challenge helps you understand recursive conditional types and JSON Schema modeling, and how to apply these concepts in real-world scenarios.
This challenge is originally from here.