-
Notifications
You must be signed in to change notification settings - Fork 328
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
Convert to JSON Schema #197
Comments
AFAIK there are possible 2 approaches
In the first case (i.e. if your source of truth is a A partial implementation interface JSONSchemaArrayRuntimeType extends t.ArrayType<JSONSchemaRuntimeType> {}
type JSONSchemaObjectRuntimeType = t.InterfaceType<{ [key: string]: JSONSchemaRuntimeType }>
type JSONSchemaRuntimeType =
| t.StringType
| t.NumberType
| t.BooleanType
| JSONSchemaArrayRuntimeType
| JSONSchemaObjectRuntimeType
export const toJSONSchema = (type: JSONSchemaRuntimeType): JSONSchema => {
switch (type._tag) {
case 'StringType':
return { type: 'string' }
case 'NumberType':
return { type: 'number' }
case 'BooleanType':
return { type: 'boolean' }
case 'ArrayType':
return { type: 'array', item: toJSONSchema(type.type) }
case 'InterfaceType':
return {
type: 'object',
properties: {
/* TODO */
}
}
}
} Note that you can try to prevent illegal conversions statically toJSONSchema(
t.type({
foo: t.undefined
})
) // static error However conversions might become tricky if there are recursive runtime types involved. The second option would be to go from a json schema to a runtime type, likely with code generation. In this case you may want to take a look at io-ts-codegen and specifically to this (partial) example |
I really like the approach of using an t.type({
lat: t.number,
lon: t.number
}).description('Geographical coordinates (WGS84 format)') Would you be interested in supporting such descriptions in |
I was looking for JSSchema myself too. Description is a bit specific, but could there be a way to associate meta data? t.type({
lat: t.number,
lon: t.number
}).metaData({
description: 'Geographical coordinates (WGS84 format)',
name: "Coordinates"
}) So it could contain anything, and be used by other iterators. I'm also looking a way to turn io-ts definitions to SQL table definitions, so meta data would be helpful there too. Naturally it should work with numbers etc too, like t.type({
lat: t.number.metaData({ name: "Latitude", description: "..."}),
lon: t.number
}) |
I'm experimenting with converting JSON schemas to io-ts. I think it makes sense to do it this way since JSONSchema is simpler than io-ts validators which are turing complete. In other words it is relatively easy to check minLength in an io-ts refinement but it is nearly impossible to check an arbitrary refinement with JSON schema. Therefore it makes sense to describe the language independent part as a JSON schema and translate it to language specific validators. |
I wrote a minimalistic CLI and moved the converter script into a separate package to make it a tiny bit more reusable. See https://www.npmjs.com/package/io-ts-from-json-schema |
NB. there's an example in the repo, which uses I'm wondering how one should add eg. the aforementioned |
I'm considering a use case where I'd like to export JSON Schema for interoperability with other tools or languages. Looking through the definition for
Type
, it seems like every instance defines a member named_tag
. However,_tag
is not part ofType
. I realize that all these various types are never combined into a union type, so it might seem to be useless. But if I'd like to do this for some known subset of types, it seems useful to be able to access _tag in some type safe way.The closest I seem to be able to come is to define a type like this:
type All = t.InterfaceType<any> | t.NumberType | ... /* all JS built-in types */;
In this case,
_tag
is public in all of these soAll
becomes a tagged union and I could switch on all the necessary cases and extract all the type information I need. Is this a reasonable approach? Is there a better one? BTW, I looked over #53 and, frankly, I could not understand most of what was being discussed in that thread.Thanks.
The text was updated successfully, but these errors were encountered: