import { ArrayType, BooleanType, IntegerType, NumberType, ObjectType, StringType } from './domain'; export type SomeJSONSchema = JSONSchemaType export type PartialSchema = Partial> type JSONType = _partial extends true ? T | undefined : T export type JSONSchemaType = (T extends number ? { type: JSONType minimum?: number maximum?: number exclusiveMinimum?: number exclusiveMaximum?: number multipleOf?: number format?: string } : T extends string ? { type: JSONType minLength?: number maxLength?: number pattern?: string format?: string } : T extends boolean ? { type: BooleanType } : T extends [any, ...any[]] ? { // JSON AnySchema for tuple type: JSONType items: { [K in keyof T]-?: JSONSchemaType & Nullable } & {length: T['length']} minItems: T['length'] } & ({maxItems: T['length']} | {additionalItems: false}) : T extends any[] ? { type: JSONType items: JSONSchemaType contains?: PartialSchema minItems?: number maxItems?: number minContains?: number maxContains?: number uniqueItems?: true additionalItems?: never } : T extends Record ? { // JSON AnySchema for records and dictionaries // 'required' is not optional because it is often forgotten // 'properties' are optional for more concise dictionary schemas // 'patternProperties' and can be only used with interfaces that have string index type: JSONType // 'required' type does not guarantee that all required properties are listed // it only asserts that optional cannot be listed required: _partial extends true ? (keyof T)[] : RequiredMembers[] additionalProperties?: boolean | JSONSchemaType unevaluatedProperties?: boolean | JSONSchemaType properties?: _partial extends true ? Partial> : PropertiesSchema patternProperties?: {[Pattern in string]?: JSONSchemaType} propertyNames?: JSONSchemaType dependencies?: {[K in keyof T]?: (keyof T)[] | PartialSchema} dependentRequired?: {[K in keyof T]?: (keyof T)[]} dependentSchemas?: {[K in keyof T]?: PartialSchema} minProperties?: number maxProperties?: number } : T extends null ? { nullable: true } : never) & { [keyword: string]: any $id?: string $ref?: string $defs?: { [Key in string]?: JSONSchemaType } definitions?: { [Key in string]?: JSONSchemaType } allOf?: PartialSchema[] anyOf?: PartialSchema[] oneOf?: PartialSchema[] if?: PartialSchema then?: PartialSchema else?: PartialSchema not?: PartialSchema } type Known = KnownRecord | [Known, ...Known[]] | Known[] | number | string | boolean | null interface KnownRecord extends Record {} type PropertiesSchema = { [K in keyof T]-?: (JSONSchemaType & Nullable) | {$ref: string} } type RequiredMembers = { [K in keyof T]-?: undefined extends T[K] ? never : K }[keyof T] type Nullable = undefined extends T ? { nullable: true const?: never // any non-null value would fail `const: null`, `null` would fail any other value in const enum?: (T | null)[] // `null` must be explicitly included in 'enum' for `null` to pass default?: T | null } : { const?: T enum?: T[] default?: T }