ajv
ajv copied to clipboard
Typescript undefined type is not supported by schema type utilities
When trying to define a Schema where one property is optional (undefined) and not null in Typescript I'm getting type errors and cannot build the typescript. I know the error states " 'nullable' is missing in type" and I have no interest treating null and undefined the same, I want only the object to be valid if it has the property of type string or not defined in the object so that is in line white the Typescript object.
What version of Ajv are you using? Does the issue happen if you use the latest version?
v8.11.0
Ajv options object
interface TheType {
key2: string | undefined;
}
const schema: JSONSchemaType<TheType> = {
additionalProperties: true,
required: [],
properties: {
key2: { type: "string" },
},
type: "object",
}
The error
Type '{ additionalProperties: true; required: never[]; properties:
{ key2: { type: "string"; }; }; type: "object"; }' is not assignable to
type 'UncheckedJSONSchemaType<TheType, false>'.
The types of 'properties.key2' are incompatible between these types.
Type '{ type: "string"; }' is not assignable to type '{ $ref: string; }
| (UncheckedJSONSchemaType<string | undefined, false>
& { nullable: true; const?: null | 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?: null | undefined;
enum?: readonly (string | null | undefined)[]
| undefined; default?: string | null | undefined; }'.
interface TheType {
key2: string | undefined;
}
const schema: JSONSchemaType<TheType> = {
additionalProperties: true,
required: [],
properties: {
key2: { nullable: false, type: "string" },
},
type: "object",
}
The error
Type '{ additionalProperties: true; required: never[]; properties: { key2: {
nullable: false; type: "string"; }; }; type: "object"; }'
is not assignable to type 'UncheckedJSONSchemaType<TheType, false>'.
The types of 'properties.key2' are incompatible between these types.
Type '{ nullable: false; type: "string"; }' is not assignable to
type '{ $ref: string; } | (UncheckedJSONSchemaType<string | undefined, false>
& { nullable: true; const?: null | undefined;
enum?: readonly (string | null | undefined)[] | undefined;
default?: string | ... 1 more ... | undefined; })'.
Types of property 'nullable' are incompatible.
Type 'false' is not assignable to type 'true'.
this is a known limitation. Type utilities for schemas support optional properties, but not unions with undefined (and you need to have strict mode on in Typescript, but it probably is).
You should use something like:
interface TheType {
key2?: string
}
(or do not use type utilities, if you must use undefined type)
Thanks, @epoberezkin for the fast feedback, but I have not gotten this to work either so I created a sample project that demonstrates the issue when I try to use the type utility ? instead of undefined to allow the key property to be either string or undefined and not null. The sample project has tests to demonstrate when I expect to be able to validate and how.
Any assistance on this issue is greatly appreciated.
https://github.com/agirorn/ajv-issue-2040-sample-project
I have exactly the same issue as @agirorn : For a property which is simply optional (i.e. marked with ?) in my Typescript interface, JSONSchemaType tries to enforce me to set the nullable option for the property in the schema, which does not make sense to me. I'd expect the property to be optional simply by not listing it in required.
Setting the nullable option gives a false hint, since the property must not be null at all - it is just optional.
By the way, I don't find any official documentation of the nullable option for JSON schema (neither at https://json-schema.org/ nor anywhere else) - where is that option specified?
nullable is not a JSON schema keyword, it was an OpenAPI/Swagger keyword.
Same case here and it cause issues with nullable arrays (nullable in ajv meaning). You can't wrap your array in a const and call it in another schema because it result in an undefined type for ts. But if you declare it directly in the object with the nullable it work. It doesn't make any sense to me. I'm sure we are all agree to say there is a big problem with the nullable in the lib.
I have exactly the same issue as @agirorn : For a property which is simply optional (i.e. marked with
?) in my Typescript interface,JSONSchemaTypetries to enforce me to set thenullableoption for the property in the schema, which does not make sense to me. I'd expect the property to be optional simply by not listing it inrequired.Setting the
nullableoption gives a false hint, since the property must not benullat all - it is just optional.By the way, I don't find any official documentation of the
nullableoption for JSON schema (neither at https://json-schema.org/ nor anywhere else) - where is that option specified?
UP !
We encounter the same problem, thanks @Wytrykus you perfectly summarized it.
It seems that AJV types definition are not consistent.
Is there any solution ? Or typing improvement proposal ?