ajv: JSONSchemaType doesn't infer nullable types
What version of Ajv are you using? Does the issue happen if you use the latest version? 8.11.2 This issue is not present in 8.11.0
Your typescript code
import { JSONSchemaType } from "ajv";
const schema: JSONSchemaType<{ foo: string | null }> = {
type: "object",
properties: {
foo: { type: "string", nullable: true },
},
required: ["foo"],
};
void schema;
Typescript compiler error messages
Type '{ type: "object"; properties: { foo: { type: "string"; nullable: true; }; }; required: "foo"[]; }' is not assignable to type 'UncheckedJSONSchemaType<{ foo: string | null; }, false>'.
The types of 'properties.foo' are incompatible between these types.
Type '{ type: "string"; nullable: true; }' is not assignable to type '{ $ref: string; } | ({ anyOf: readonly UncheckedJSONSchemaType<string | null, false>[]; } & { [keyword: string]: any; $id?: string | undefined; $ref?: string | undefined; $defs?: Record<...> | undefined; definitions?: Record<...> | undefined; } & { ...; }) | ({ ...; } & ... 1 more ... & { ...; }) | ({ ...; } & ... 2...'.
Types of property 'nullable' are incompatible.
Type 'true' is not assignable to type 'false'.ts(2322)
Describe the change that should be made to address the issue? There should be no TypeScript errors. As mentioned, this does not give any compiler errors in version 8.11.0
Are you going to resolve the issue? I’m not familiar with the internals of ajv
About this issue
- Original URL
- State: open
- Created 2 years ago
- Reactions: 26
- Comments: 15
Seem’s that this is a bug introduced with the commit https://github.com/ajv-validator/ajv/commit/00b3939ba545e87f585b5ee5e93d26f025454fc6
IMO it’s against the JSON Schema specification.
JSON Schema imposes no restrictions on type: JSON Schema can describe any JSON value, including, for example, null
http://json-schema.org/draft/2020-12/json-schema-core.htmlAnd from the link @juliensnz posted
It’s important to remember that in JSON, null isn’t equivalent to something being absent.
With this change, it became impossible to define a required field that has a null value.
While it should be perfectly fine.
By the way, from this commit message “nullable was enforced for optional parameters” - I think this is also wrong. I might want to have an optional, string field that can’t be null if it’s present. In this case only a string should be accepted or undefined value.
null
shouldn’t be accepted.Nullable
andnon-required
are different things similarly asnull
and “absent” are different concepts in JSON.As a workaround I found that this works:
(though I’m not happy about it)
another solution (not prettier) could be to do:
I will top this all with this workaround:
Just see it as a Zen Koan
Hello everyone, who is encountered this issue! What helped me here to get rid of this issue at least temporary:
ajv
version8.11.0
typescript
version5.0.4
: for exampletypescript 5.2.2
proceeded reproduce this issue even with previously mentioned item.Overall, looks like issue connected not only with ajv, but with typescript dependency changes too, unfortunately, there is not enough time for taking deeper look into possible reasons. Hope, that it will help someone to resolve it locally in your projects and maybe found the root cause and fix it in the next update.
This probably doesn’t help but it appears if you make the field optional (e.g. add
?
) then the schema works.e.g.
In my case ajv was coercing
null
values to0
since the nullable field was an integer – by adding?
I was able to addnullable: true
and ajv also stopped coercing.