Skip to content
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

Compute TypeScript type #78

Open
JSteunou opened this issue Aug 5, 2020 · 10 comments
Open

Compute TypeScript type #78

JSteunou opened this issue Aug 5, 2020 · 10 comments
Labels
enhancement New feature or request

Comments

@JSteunou
Copy link

JSteunou commented Aug 5, 2020

🚀 Feature Proposal

I think it will be possible and convenient to add a way to expose the TypeScript type of each object schema

Motivation

I started, like the doc of fastify suggest, to use fluent-schema (which is awesome!) and json-schema-to-typescript to generate types... in separate files.

Also this method could be ok for those who prefer having separate files, separate schema & types, I am not a big fan of depending on a script to re-generate those types. And even with a banner saying do not modify this file, update the schema instead, this could be error prone.

Another way to handle the case would be to add the capacity to fluent-schema to generate types directly. It would allow users to export a schema and the matching interface or type from the same module, not depending on scripts, not having several files, not having a type written that can be modified, not having another library, ... You got the point, it would be just simpler :)

Example

To my opinion, a good example of API for this case is mobx-state-tree which allow to generate Interface or Type from a model

import {Instance} from 'mobx-state-tree'

const Todo = types
    .model({
        title: "hello",
        done: false,
    })

interface ITodo extends Instance<typeof Todo> {}
// => {title: string, done: boolean}

type TTodo = typeof Todo.Type
// => {title: string, done: boolean}

The helper Instance is from MobX State Tree here, not a TypeScript helper.

The bad news is, I don't know how to do this myself, but I can learn and help if needed 🙏

@mcollina
Copy link
Member

mcollina commented Aug 5, 2020

I think this is hard to do, but maybe it got easier!

An alternative approach is https://github.com/sinclairzx81/typebox!

@JSteunou
Copy link
Author

JSteunou commented Aug 5, 2020

I think it depends if you wanna be full JSON Schema compliant. $ref might be the most difficult point to solve because it can be async.

I will try typebox, sounds nice. I also discover https://github.com/keplr-team/typed-ajv which has the same approach than typebox. The trick is to define types of each function helper which define properties.

@aboutlo
Copy link
Collaborator

aboutlo commented Aug 5, 2020

It's an interesting feature, not sure how to tackle it. I have the feeling we need to bring an important part of the codebase in Typescript to deliver this. However, currently, I haven't bandwidth. But you are welcome to open a PR even with just as POC so we can maybe figure out the approach.

@JSteunou
Copy link
Author

JSteunou commented Aug 5, 2020

Another example, for the record, that could help to build this feature, using TypeScript Conditional Types https://medium.com/@tiagosemoh/typescript-advanced-types-b17ad54a831e

This is the base of this library https://github.com/TCMiranda/joi-extract-type which seems very underestimated

I dunno if I would have the time to write a POC, having a bandwidth also very full :( So I share any resource I can find.

@aboutlo aboutlo added the enhancement New feature or request label Aug 6, 2020
@gc
Copy link

gc commented Aug 6, 2020

Thank you so much for sharing typebox, I had the exact same issue in fluent-schema and typebox seems perfect.

Here's some example code for fastify if it helps anyone:

import { Type, Static } from '@sinclair/typebox';

const BodySchema = Type.Object({
	email: Type.String({ format: 'email' }),
	address: Type.String(),
});

server.route<{ Body: Static<typeof BodySchema> }>({
	method: 'GET',
	url: '/example',
	schema: {
		body: BodySchema
	},
	async handler(request, reply) {
		request.body.email;
	}
});

@aboutlo
Copy link
Collaborator

aboutlo commented Aug 6, 2020 via email

@RishabhJain96
Copy link

With Typescript 4.1, it might be possible to generate a typescript model from the JSON schema. If people are interested, check out this library (still in beta): https://github.com/RishabhJain96/json-schema-type

(Comment copied from fastify/fastify#1668)

@calebboyd
Copy link

calebboyd commented Jan 27, 2021

Some other art for types w/ fluent builder

https://github.com/sberan/typed-json-schema/tree/next

@Coobaha
Copy link

Coobaha commented Feb 18, 2021

Hi! please also check https://github.com/Coobaha/typed-fastify - very alpha release but works nicely :)

It requires TS ^4.2 and provides strongly typed handlers against defined schema and runtime validations by using generated json schema from types. It enforces developer to respond with status, headers and payload that are matching schema.

Small demo:

2021-02-18_19-50-09.mp4

@misha-erm
Copy link

Was thinking about using https://github.com/ThomasAribart/json-schema-to-ts but TypeBox seems a bit nicer option here since it gives concise API and all the autocompletes

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

8 participants