Skip to content

Instantly share code, notes, and snippets.

@mattiamanzati
Created August 30, 2017 15:59
Show Gist options
  • Save mattiamanzati/9b9439249e3d749bb9ad66aa4d716509 to your computer and use it in GitHub Desktop.
Save mattiamanzati/9b9439249e3d749bb9ad66aa4d716509 to your computer and use it in GitHub Desktop.
import { IType, IExtendedObservableMap } from "mobx-state-tree"
import { IObservableArray } from "mobx"
type StringContains<S extends string, L extends string> = ({ [K in S]: "true" } & {
[key: string]: "false"
})[L]
interface IJSONSchemaBaseType {
$schema?: string
$id?: string
default?: any
}
interface IJSONSchemaNumber extends IJSONSchemaBaseType {
type: "number"
multipleOf?: number
maximum?: number
minimum?: number
exclusiveMaximum?: number
exclusiveMinimum?: number
}
interface IJSONSchemaInteger extends IJSONSchemaBaseType {
type: "integer"
multipleOf?: number
maximum?: number
minimum?: number
exclusiveMaximum?: number
exclusiveMinimum?: number
}
interface IJSONSchemaNull extends IJSONSchemaBaseType {
type: "null"
}
interface IJSONSchemaString extends IJSONSchemaBaseType {
type: "string"
minLength?: number
maxLength?: number
pattern?: string
}
interface IJSONSchemaBoolean extends IJSONSchemaBaseType {
type: "boolean"
}
interface IJSONSchemaArray extends IJSONSchemaBaseType {
type: "array"
items: IJSONSchema6
}
interface IJSONSchemaObject extends IJSONSchemaBaseType {
type: "object"
properties: { [K: string]: IJSONSchema6 }
}
interface IJSONSchemaOneOf extends IJSONSchemaBaseType {
oneOf: IJSONSchema6[]
}
type IJSONSchemaPrimitive =
| IJSONSchemaInteger
| IJSONSchemaNull
| IJSONSchemaNumber
| IJSONSchemaString
| IJSONSchemaBoolean
type IJSONSchemaSimple = IJSONSchemaPrimitive | IJSONSchemaObject | IJSONSchemaArray
type IJSONSchema6 = IJSONSchemaSimple | IJSONSchemaOneOf
// type ObjectInterface<T extends IJSONSchemaObject> = {
// [K in keyof T["properties"]]: InterfaceFromSchema<T["properties"][K]>
// }
// type InterfaceFromSchema<T extends IJSONSchema6> = {
// number: number
// integer: number
// null: null
// string: string
// boolean: boolean
// array: InterfaceFromSchema<T["items"]>[]
// object: ObjectInterface<T>
// union: InterfaceFromSchema<T["oneOf"][0]> | InterfaceFromSchema<T["oneOf"][1]>
// }[T["type"]]
type MSTObjectTypeInterface<T extends IJSONSchemaObject> = {
[K in keyof T["properties"]]: MSTFromSchema<T["properties"][K]>["Type"]
}
type MSTObjectSnapshotTypeInterface<T extends IJSONSchemaObject> = {
[K in keyof T["properties"]]?: MSTFromSchema<T["properties"][K]>["SnapshotType"]
}
type MSTFromSimpleSchema<T extends IJSONSchemaSimple> = {
number: IType<number, number>
integer: IType<number, number>
null: IType<null, null>
string: IType<string, string>
boolean: IType<boolean, boolean>
array: IType<
MSTFromSchema<T["items"]>["SnapshotType"][],
IObservableArray<MSTFromSchema<T["items"]>["Type"]>
>
object: IType<MSTObjectSnapshotTypeInterface<T>, MSTObjectTypeInterface<T>>
}[T["type"]]
type MSTFromSchema<T extends IJSONSchema6> = {
false: IType<42, 42>
true: IType<
MSTFromSchema<T["oneOf"][number]>["SnapshotType"],
MSTFromSchema<T["oneOf"][number]>["Type"]
>
}[StringContains<keyof T, "oneOf">]
declare function compile<T extends IJSONSchema6>(schema: T): MSTFromSchema<T>
const complex = { type: "array", items: { type: "boolean" } }
// dovrebbe essere IType, non 42 :/
const testUnion1 = compile({
oneOf: [{ type: "array", items: { type: "boolean" } }]
})
const testUnion2 = compile({
oneOf: [{ type: "null" }, { type: "number" }]
})
const testUnion3 = compile({
oneOf: [{ type: "number" }, { type: "string" }, { type: "boolean" }]
})
declare const a: MSTFromSchema<{
oneOf: [{ type: "array"; items: { type: "boolean" } }]
}>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment