1 /* eslint-disable @typescript-eslint/no-empty-interface */
2 export type SomeJSONSchema = JSONSchemaType<Known, true>
4 export type PartialSchema<T> = Partial<JSONSchemaType<T, true>>
6 type JSONType<T extends string, _partial extends boolean> = _partial extends true
10 interface NumberKeywords {
13 exclusiveMinimum?: number
14 exclusiveMaximum?: number
19 interface StringKeywords {
26 export type JSONSchemaType<T, _partial extends boolean = false> = (
29 type: JSONType<"number" | "integer", _partial>
33 type: JSONType<"string", _partial>
39 : T extends [any, ...any[]]
41 // JSON AnySchema for tuple
42 type: JSONType<"array", _partial>
44 readonly [K in keyof T]-?: JSONSchemaType<T[K]> & Nullable<T[K]>
45 } & {length: T["length"]}
47 } & ({maxItems: T["length"]} | {additionalItems: false})
48 : T extends readonly any[]
50 type: JSONType<"array", _partial>
51 items: JSONSchemaType<T[0]>
52 contains?: PartialSchema<T[0]>
58 additionalItems?: never
60 : T extends Record<string, any>
62 // JSON AnySchema for records and dictionaries
63 // "required" is not optional because it is often forgotten
64 // "properties" are optional for more concise dictionary schemas
65 // "patternProperties" and can be only used with interfaces that have string index
66 type: JSONType<"object", _partial>
67 // "required" type does not guarantee that all required properties are listed
68 // it only asserts that optional cannot be listed
69 required: _partial extends true ? Readonly<(keyof T)[]> : Readonly<RequiredMembers<T>[]>
70 additionalProperties?: boolean | JSONSchemaType<T[string]>
71 unevaluatedProperties?: boolean | JSONSchemaType<T[string]>
72 properties?: _partial extends true ? Partial<PropertiesSchema<T>> : PropertiesSchema<T>
73 patternProperties?: {[Pattern in string]?: JSONSchemaType<T[string]>}
74 propertyNames?: JSONSchemaType<string>
75 dependencies?: {[K in keyof T]?: Readonly<(keyof T)[]> | PartialSchema<T>}
76 dependentRequired?: {[K in keyof T]?: Readonly<(keyof T)[]>}
77 dependentSchemas?: {[K in keyof T]?: PartialSchema<T>}
78 minProperties?: number
79 maxProperties?: number
86 allOf?: Readonly<PartialSchema<T>[]>
87 anyOf?: Readonly<PartialSchema<T>[]>
88 oneOf?: Readonly<PartialSchema<T>[]>
90 then?: PartialSchema<T>
91 else?: PartialSchema<T>
92 not?: PartialSchema<T>
94 // these two unions allow arbitrary unions of types
96 anyOf: readonly JSONSchemaType<T, _partial>[]
99 oneOf: readonly JSONSchemaType<T, _partial>[]
101 // this union allows for { type: (primitive)[] } style schemas
103 type: (T extends number
104 ? JSONType<"number" | "integer", _partial>
106 ? JSONType<"string", _partial>
108 ? JSONType<"boolean", _partial>
110 } & (T extends number
118 [keyword: string]: any
122 [Key in string]?: JSONSchemaType<Known, true>
125 [Key in string]?: JSONSchemaType<Known, true>
129 type Known = KnownRecord | [Known, ...Known[]] | Known[] | number | string | boolean | null
131 interface KnownRecord extends Record<string, Known> {}
133 export type PropertiesSchema<T> = {
134 [K in keyof T]-?: (JSONSchemaType<T[K]> & Nullable<T[K]>) | {$ref: string}
137 export type RequiredMembers<T> = {
138 [K in keyof T]-?: undefined extends T[K] ? never : K
141 type Nullable<T> = undefined extends T
144 const?: never // any non-null value would fail `const: null`, `null` would fail any other value in const
145 enum?: Readonly<(T | null)[]> // `null` must be explicitly included in "enum" for `null` to pass