question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

JSONSchemaType incorrectly requires optional properties to be nullable

See original GitHub issue

What version of Ajv are you using? Does the issue happen if you use the latest version?

Ajv 8.6.0, Typescript 4.3.4

Your typescript code

import { JSONSchemaType } from 'ajv/dist/2020';

interface Example {
  foo: string;
  bar?: string;
}

const schema: JSONSchemaType<Example> = {
  additionalProperties: false,
  type: 'object',
  properties: {
    foo: {
      type: 'string'
    },
    bar: {
      type: 'string'
    }
  },
  required: ['foo']
};

Typescript compiler error messages

TS2322: Type '{ additionalProperties: false; type: "object"; properties: { foo: { type: "string"; }; bar: { type: "string"; }; }; required: "foo"[]; }' is not assignable to type 'UncheckedJSONSchemaType<Example, false>'.
  Type '{ additionalProperties: false; type: "object"; properties: { foo: { type: "string"; }; bar: { type: "string"; }; }; required: "foo"[]; }' is not assignable to type '{ type: "object"; additionalProperties?: boolean | UncheckedJSONSchemaType<unknown, false> | undefined; unevaluatedProperties?: boolean | UncheckedJSONSchemaType<unknown, false> | undefined; ... 7 more ...; maxProperties?: number | undefined; } & { ...; } & { ...; } & { ...; }'.
    Type '{ additionalProperties: false; type: "object"; properties: { foo: { type: "string"; }; bar: { type: "string"; }; }; required: "foo"[]; }' is not assignable to type '{ type: "object"; additionalProperties?: boolean | UncheckedJSONSchemaType<unknown, false> | undefined; unevaluatedProperties?: boolean | UncheckedJSONSchemaType<unknown, false> | undefined; ... 7 more ...; maxProperties?: number | undefined; }'.
      The types of 'properties.bar' are incompatible between these types.
        Type '{ type: "string"; }' is not assignable to type '{ $ref: string; } | (UncheckedJSONSchemaType<string | undefined, false> & { nullable: true; const?: undefined; enum?: readonly (string | null | undefined)[] | undefined; default?: string | ... 1 more ... | undefined; })'.
          Type '{ type: "string"; }' is not assignable to type '{ type: "string"; } & StringKeywords & { allOf?: readonly UncheckedPartialSchema<string | undefined>[] | undefined; anyOf?: readonly UncheckedPartialSchema<string | undefined>[] | undefined; ... 4 more ...; not?: UncheckedPartialSchema<...> | undefined; } & { ...; } & { ...; }'.
            Property 'nullable' is missing in type '{ type: "string"; }' but required in type '{ nullable: true; const?: undefined; enum?: readonly (string | null | undefined)[] | undefined; default?: string | null | undefined; }'.

Describe the change that should be made to address the issue?

This code will not compile unless bar is marked as nullable in the schema. However, I don’t want to accept null as a value for bar if it is present. It appears that JSONSchemaType expects all properties not mentioned in the required array to be marked as nullable. null and undefined are different values and should not be conflated.

Are you going to resolve the issue? 🤷

Issue Analytics

  • State:open
  • Created 2 years ago
  • Reactions:13
  • Comments:13 (5 by maintainers)

github_iconTop GitHub Comments

7reactions
reggicommented, Jan 7, 2022

Hey future traveler 👋

I just discovering this post and was about to give up, when I saw nullable: true and it worked!

Here’s a clear example:

export const schema: JSONSchemaType<{ value: string, embed?: string, page?: string}> = {
    type: "object",
    properties: {
        value: {
            type: 'string',
        },
        embed: {
            type: 'string',
            nullable: true
        },
        page: {
            type: 'string',
            nullable: true
        },
    },
    required: ['value'],
    additionalProperties: false
}
5reactions
epoberezkincommented, Jul 4, 2021

@erikbrinkman i think the correct way to improve it in the next major version is to only require nullable: true if the property has null as possible value in typescript, independently of whether it’s required or optional. That will be a breaking change.

Read more comments on GitHub >

github_iconTop Results From Across the Web

Ajv JSONSchemaType error using typescript - Stack Overflow
Since your interface says that some properties can be undefined, you have to add that into your schema as nullable: true -
Read more >
Defining Optional Properties and Nullable Values in RAML
A property is required if the presence of the property is mandatory in the JSON payload. Thus, an optional property is a property...
Read more >
OpenAPI Specification - Version 3.0.3 - Swagger
contains a required openapi field which designates the semantic version of the OAS that it uses. ... Primitives have an optional modifier property:...
Read more >
Schema generation rules · GitBook - Goswagger.Io
Loosely speaking, a swagger schema corresponds to a JSONSchema-draft4 ... to accept null values (otherwise not accepted by Swagger); required property ...
Read more >
OpenAPI Specification v3.0.3 | Introduction, Definitions, & More
required ; enum. The following properties are taken from the JSON Schema definition but their definitions were adjusted to the OpenAPI ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found