Skip to content

codegen from JSON Schema? #19

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Closed
moltar opened this issue Apr 28, 2020 · 4 comments
Closed

codegen from JSON Schema? #19

moltar opened this issue Apr 28, 2020 · 4 comments

Comments

@moltar
Copy link

moltar commented Apr 28, 2020

Wondering if there are any plans for this, and if not, would this be an interesting addition?

E.g. given a JSON Schema -> generate typebox definitions.

@sinclairzx81
Copy link
Owner

sinclairzx81 commented Apr 29, 2020

Hi, thanks for the suggestion :)

There are no immediate plans to generate TypeBox code from JSON Schema (at least not within the context of this project). Actually, TypeBox was originally written to try and avoid code generation entirely :D Basically an attempt to try and mitigate the need for external CLI tooling and rely purely on the capabilities of TypeScript. However, code generation is an important part of some projects, so I'm certainly not adverse to the idea. (maybe a typebox-codegen cli project?)

If you're interested tho, I have explored on some level the ability to 'infer' TS types directly from JSONSchema. Below is some starter code if you would like to experiment around on that front, should just be able to copy and paste into any TS editor for it to infer the type Foo from the given Schema. This would be more inline with TypeBox specifically (code inference all in) :)

Cheers man
S

// Infer directly from JSONSchema
export type ObjectSchemaProperties = { [key: string]: AnySchema }
export type ObjectSchema<T extends ObjectSchemaProperties> = { type: "object", properties: T }
export type ArraySchema<T extends AnySchema> = { type: "array", items: T }
export type NumberSchema = { type: "number" }
export type BooleanSchema = { type: "boolean" }
export type StringSchema = { type: "string" }
export type NullSchema = { type: "null" }
export type AnySchema =
    | ObjectSchema<any>
    | ArraySchema<any>
    | NumberSchema
    | BooleanSchema
    | StringSchema
    | NullSchema

export type Infer<T extends AnySchema> =
    T extends ObjectSchema<infer P> ? { -readonly [K in keyof P]: Infer<P[K]> } :
    T extends ArraySchema<infer P> ? Array<Infer<P>> :
    T extends NumberSchema ? number :
    T extends StringSchema ? string :
    T extends BooleanSchema ? boolean :
    T extends NullSchema ? null :
    unknown

// Test code
const FooSchema = {
    "type": "object",
    "properties": {
        "a": { "type": "number" },
        "b": { "type": "boolean" },
        "c": { "type": "string" },
        "d": {
            "type": "array",
            "items": { "type": "string" }
        }
    }
} as const // 'as const' is required

type Foo = Infer<typeof FooSchema> // inferred

@moltar
Copy link
Author

moltar commented Apr 29, 2020

Actually, TypeBox was originally written to try and avoid code generation entirely

I am generally aligned with this vision of code-first approach.

But sometimes schema definitions can come from third parties. Many orgs publish the API specs as JSON Schema or OpenAPI definitions. Think Kubernetes or Azure.

And it could be immensely useful to codegen interfaces and validation for those definitions.

@sinclairzx81
Copy link
Owner

Would be useful for sure. Some of those schemas can be fairly unwieldy. It's a cool idea, It's just im not sure it belongs as part of this project specifically. Unless you had something specific in mind?

I expect there would be quite a few ways to approach code generation from any given schema. I guess if I were to approach something like this, i'd try and isolate the codegen concerns in a separate GH repository (perhaps under the name of typebox-codegen or similar) and publish to npm as some optional installable CLI tooling for those who need it.

Did you have something in mind in terms of overall functionality? I expect most schemas would be published under some public URL, with perhaps the name of the TypeBox type assuming the name of the URI resource. Would such tooling also allow one to generate from schemas saved to disk? How would users rename the types if they needed?

As I say, given the nature of TypeBox, I haven't really spent too much time thinking about codegen for it. But i do note there exists similar tooling for io-ts out there, for example https://github.com/gcanti/io-ts-codegen, so there does seem to be others thinking along these lines too. Would this be kinda what you had in mind?

I don't think this is something id be able to spend much time looking in the near term however, but would be happy to provide some assistance with a codegen implementation if you want to have a go approaching it. I do actually need some code generation tech for this project. Maybe there is some crossover there.

Cheers mate, Look forward to getting your thoughts.
S

@moltar
Copy link
Author

moltar commented Apr 30, 2020

It's just im not sure it belongs as part of this project specifically

Right, I agree that it should probably be a separate package. As the concerns are aligned, yet different.

Did you have something in mind in terms of overall functionality?

Basically, in simple terms, feed it JSON Schema and get Typebox definitions coming out. But I didn't think it thru that much yet.


Thanks for your input.

I'm going close this issue for now, as it's not an issue.

I will report back, when/if I do work on this.

# for free to join this conversation on GitHub. Already have an account? # to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants