Created
August 30, 2017 15:03
-
-
Save mattiamanzati/7644674c0e94ad32c2cc71bf9887ad37 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
type StringContains<S extends string, L extends string> = ({ [K in S]: "true" } & { | |
[key: string]: "false" | |
})[L] | |
interface IJSONSchemaNumber { | |
type: "number" | |
} | |
interface IJSONSchemaInteger { | |
type: "integer" | |
} | |
interface IJSONSchemaNull { | |
type: "null" | |
} | |
interface IJSONSchemaString { | |
type: "string" | |
} | |
interface IJSONSchemaBoolean { | |
type: "boolean" | |
} | |
interface IJSONSchemaArray { | |
type: "array" | |
items: IJSONSchemaType | |
} | |
interface IJSONSchemaObject { | |
type: "object" | |
properties: { [K: string]: IJSONSchemaType } | |
} | |
interface IJSONSchemaUnion { | |
anyOf: IJSONSchemaType[] | |
} | |
type IJSONSchemaPrimitive = | |
| IJSONSchemaInteger | |
| IJSONSchemaNull | |
| IJSONSchemaNumber | |
| IJSONSchemaString | |
| IJSONSchemaBoolean | |
type IJSONSchemaType = | |
| IJSONSchemaPrimitive | |
| IJSONSchemaObject | |
| IJSONSchemaArray | |
| IJSONSchemaUnion | |
type ObjectType<T extends IJSONSchemaObject> = { | |
[K in keyof T["properties"]]: InterfaceFromSchema<T["properties"][K]> | |
} | |
type PrimitiveFromSchema<T extends IJSONSchemaPrimitive> = { | |
number: number | |
integer: number | |
null: null | |
string: string | |
boolean: boolean | |
array: InterfaceFromSchema<T["items"]>[] | |
object: ObjectType<T> | |
}[T["type"]] | |
type InterfaceFromSchema<T extends IJSONSchemaType> = { | |
true: 42 | |
false: PrimitiveFromSchema<T> | |
}[StringContains<keyof T, "anyOf">] | |
declare function compile<T extends IJSONSchemaType>(schema: T): InterfaceFromSchema<T> | |
const number = compile({ type: "number" }) | |
const integer = compile({ type: "integer" }) | |
const nulls = compile({ type: "null" }) | |
const string = compile({ type: "string" }) | |
const boolean = compile({ type: "boolean" }) | |
const object = compile({ type: "object", properties: { amount: { type: "boolean" } } }) | |
const array = compile({ type: "array", items: { type: "boolean" } }) | |
const arrayOfObject = compile({ | |
type: "array", | |
items: { type: "object", properties: { amount: { type: "boolean" } } } | |
}) | |
const objectWithArray = compile({ | |
type: "object", | |
properties: { amount: { type: "array", items: { type: "boolean" } } } | |
}) | |
const complex = compile({ | |
type: "object", | |
properties: { | |
_id: { type: "string" }, | |
document_id: { type: "integer" }, | |
article_id: { type: "integer" }, | |
qty: { type: "number" }, | |
price: { type: "number" }, | |
value: { type: "number" }, | |
rows: { | |
type: "array", | |
items: { | |
type: "object", | |
properties: { | |
_id: { type: "string" }, | |
document_id: { type: "integer" }, | |
article_id: { type: "integer" }, | |
qty: { type: "number" }, | |
price: { type: "number" }, | |
value: { type: "number" } | |
} | |
} | |
} | |
} | |
}) | |
// qui va sempre in false | |
const a = compile({ | |
anyOf: [{ type: "number" }, { type: "boolean" }] | |
}) | |
// anche se qui è true :/ | |
const b: StringContains< | |
keyof { | |
anyOf: [{ type: "number" }, { type: "boolean" }] | |
}, | |
"anyOf" | |
> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment