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

JSONSchemaType allows schemas with optional attributes for Types where they are required #2030

Closed
slifty opened this issue Jul 11, 2022 · 3 comments · Fixed by #2079
Closed

Comments

@slifty
Copy link

slifty commented Jul 11, 2022

What version of Ajv are you using? Does the issue happen if you use the latest version?
Using 8.11.0 (latest)

Ajv options object

No options are set

export const ajv = new Ajv();

JSON Schema

interface MyExample {
  foo: number;
}
const myExampleSchema: JSONSchemaType<MyExample> = {
  type: 'object',
  properties: {
    foo: {
      type: 'number',
      nullable: true,
    },
  },
  required: [],
}

Validation result, data AFTER validation, error messages

No static analysis issues come out of TypeScript -- it's considered a valid schema for that type.

What results did you expect?

I expected a TypeScript error saying something along the lines of "foo?" is incompatible with type "foo"

Are you going to resolve the issue?

I don't think I know how to, but happy to make an effort if this is indeed a valid bug.

@epoberezkin
Copy link
Member

yes, typescript type utilities are not perfect - they push the limits of typescript to the point of type analyser (and my brain) cracking at seams - no way we can complicate it further, I am afraid...

cc @erikbrinkman, just in case I am wrong.

erikbrinkman added a commit to erikbrinkman/ajv that referenced this issue Sep 2, 2022
nullable was enforced for optional parameters, but not forbidden for
required parameters. This tests and enforces the latter case.

fixes ajv-validator#2030
@erikbrinkman
Copy link
Collaborator

There are two different issues here. The first was ensuring that nullable is false or absent. That was actually a bug that I just submitted a PR for.

The second is that required should have all non-null keys. The unfortunately is not possible in typescript. In the world we're talking about, the true type for required is all permutations of tuples of all the keys, e.g. the type ["a", "b"] or the type ["b", "a"]. There are some other discussions about this, but for various reasons this just isn't possible. If you really want this level of type checking you should look at JTD because its structure is more compatible with typescript's type system.

Thus after the PR your example will fail, but:

interface MyExample {
  foo: number;
}
const myExampleSchema: JSONSchemaType<MyExample> = {
  type: 'object',
  properties: {
    foo: {
      type: 'number',
    },
  },
  required: [],
}

will still pass, and there's not much JSONSchemaType can do about it. At least with my current awareness of the typescript type system. It may have been expanded recently, but I doubt it.

@slifty
Copy link
Author

slifty commented Sep 3, 2022

Thank you both for engaging with this and for that bug fix -- honestly that alone will go a long way.

(I also want to mention how thankful I am for the TypeScript support that you've built into this library, it's really excellent and I appreciate how complicated it must have been to implement!)

epoberezkin added a commit that referenced this issue Nov 13, 2022
nullable was enforced for optional parameters, but not forbidden for
required parameters. This tests and enforces the latter case.

fixes #2030

Co-authored-by: Evgeny Poberezkin <2769109+epoberezkin@users.noreply.github.com>
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.

3 participants