Home > OS >  Ajv JSONSchemaType error using typescript
Ajv JSONSchemaType error using typescript

Time:11-05

I'm having an issue writing a validator with 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"'.",

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?

Thanks in advanced, Humberto

CodePudding user response:

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.

Playground

  • Related