I'm having an issue writing a validator with Ajv and typescript.
Here is the definition of my schema
import Ajv, { JSONSchemaType } from "ajv";
const ajv = new Ajv();
interface Attribute {
name: string;
type: string;
ref?: boolean;
cardinality?: string;
optional?: boolean;
}
interface Concept {
type: string;
root?: boolean;
attributes?: Array<Attribute>;
hidden?: boolean;
terminal?: boolean;
expression?: string;
}
const properties = {
name: { type: "string" },
type: { type: "string" },
ref: { type: "boolean" },
cardinality: { type: "string"},
optional: { type: "boolean" },
};
const conceptSchema: JSONSchemaType<Concept> = {
type: "object",
properties: {
type: { type: "string" },
root: { type: "boolean"},
attributes: {
type: "array",
uniqueItems: true,
items: {
type: "object",
properties: properties,
required: ["name", "type"],
},
},
hidden: { type: "boolean" },
terminal: { type: "boolean" },
expression: { type: "string" },
},
required: ["type"],
additionalProperties: false,
};
Any idea why I'm getting the following error using ajv and typescript?
"message": "Type '{ type: "object"; properties: { type: { type: "string"; }; root: { type: "boolean"; }; attributes: { type: "array"; uniqueItems: true; items: { type: "object"; properties: { name: { type: string; }; type: { type: string; }; ref: { ...; }; cardinality: { ...; }; optional: { ...; }; }; required: ("type" | "name")[]; }...' is not assignable to type 'UncheckedJSONSchemaType<Concept, false>'.\n The types of 'properties.attributes' are incompatible between these types.\n
Type '{ type: "array"; uniqueItems: true; items: { type: "object"; properties: { name: { type: string; }; type: { type: string; }; ref: { type: string; }; cardinality: { type: string; pattern: string; }; optional: { type: string; }; }; required: ("type" | "name")[]; }; }' is not assignable to type '{ $ref: string; } | (UncheckedJSONSchemaType<Attribute[] | undefined, false> & { nullable: true; const?: null | undefined; enum?: readonly (Attribute[] | null | undefined)[] | undefined; default?: Attribute[] | ... 1 more ... | undefined; })'.\n Types of property 'items' are incompatible.\n
Type '{ type: "object"; properties: { name: { type: string; }; type: { type: string; }; ref: { type: string; }; cardinality: { type: string; pattern: string; }; optional: { type: string; }; }; required: ("type" | "name")[]; }' is not assignable to type 'UncheckedJSONSchemaType<Attribute, false>'.\n The types of 'properties.name' are incompatible between these types.\n
Type '{ type: string; }' is not assignable to type '{ $ref: string; } | (UncheckedJSONSchemaType<string, false> & { const?: string | undefined; enum?: readonly string[] | undefined; default?: string | undefined; })'.\n Type '{ type: string; }' is not assignable to type '{ type: "string"; } & StringKeywords & { allOf?: readonly UncheckedPartialSchema[] | undefined; anyOf?: readonly UncheckedPartialSchema[] | undefined; ... 4 more ...; not?: UncheckedPartialSchema<...> | undefined; } & { ...; } & { ...; }'.\n Type '{ type: string; }' is not assignable to type '{ type: "string"; }'.\n Types of property 'type' are incompatible.\n Type 'string' is not assignable to type '"string"'.",
Since your interface says that some properties can be undefined, you have to add that into your schema as nullable: true
-
const conceptSchema: JSONSchemaType<Concept> = {
type: "object",
properties: {
type: { type: "string" },
root: { type: "boolean", nullable: true },
attributes: {
type: "array",
uniqueItems: true,
items: {
type: "object",
properties: {
name: { type: "string" },
type: { type: "string" },
ref: { type: "boolean", nullable: true },
cardinality: { type: "string", nullable: true },
optional: { type: "boolean", nullable: true },
},
required: ["name", "type"],
},
nullable: true,
},
hidden: { type: "boolean", nullable: true },
terminal: { type: "boolean", nullable: true },
expression: { type: "string", nullable: true },
},
required: ["type"],
additionalProperties: false,
};
Also note that I have inlined the constant properties
so it won't be inferred incorrectly.