Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

strictTypes does not expect "narrowing" integer with number keywords #1935

Closed
JacobLey opened this issue Mar 22, 2022 · 2 comments
Closed

strictTypes does not expect "narrowing" integer with number keywords #1935

JacobLey opened this issue Mar 22, 2022 · 2 comments
Milestone

Comments

@JacobLey
Copy link
Contributor

JacobLey commented Mar 22, 2022

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

8.10.0
With all included schemas (default, 2019, 2020)

Ajv options object

{ strictTypes: true }

JSON Schema

{
    "type": "number",
    "if": {
        "type": "integer",
        "maximum": 5
     },
     "else": {
         "minimum": 10
     }
}

In english:
A number that must be an integer <= 5, or any number >= 10.

Sample data

Resolves as follows if strictTypes is 'log' or false

4 // valid
4.5 // invalid
7 // invalid
11.5 // valid
"" // invalid
null // invalid

Your code

new Ajv({ strictTypes: true }).compile({
    type: 'number',
    if: {
        type: 'integer',
        maximum: 5
     },
     else {
         minimum: 10
     }
});

Validation result, data AFTER validation, error messages

Error: strict mode: missing type "number" for keyword "maximum" at "#/if" (strictTypes)

What results did you expect?
No error message.

Documentation of strictTypes

"number" vs "integer"
Type "number" can be narrowed to "integer", the opposite would violate strictTypes.

maximum is a valid keyword for integer type, which is a "narrowing" of number.

Note that the else does not error on missing type: 'number' and the error goes away if type: 'integer' is removed (as type is properly inferred from parent schema). Error also goes away if maximum: 5 is removed.

Dropping type: 'integer' or maximum: 5, would logically alter schema, as above examples of 4.5 and 7 would then be valid.

Are you going to resolve the issue?
Current local solution for me is to drop strictTypes (which does not impact validation, but is an overall appreciated feature).

I'd be open to taking a swing at resolving, but would probably need some serious guidance on where to even start.

@JacobLey
Copy link
Contributor Author

new Ajv({ strictTypes: true }).compile({
    type: 'number',
    if: {
        allOf: [
            { type: 'integer' },
            { maximum: 5 }
        ]
     },
     else {
         minimum: 10
     }
});

Appears to perform as expected with no errors. But IMHO that makes the schema less readable, and should not be necessary given the documentation of strictTypes handling of number -> integer

@epoberezkin
Copy link
Member

yes, agreed, the logic for tracking types should be extended to ifs

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Development

Successfully merging a pull request may close this issue.

2 participants