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

Validate function narrowing behavior not working with typescript 5.1 #2293

Open
Baptiste-Garcin opened this issue Jun 20, 2023 · 2 comments
Open

Comments

@Baptiste-Garcin
Copy link

Baptiste-Garcin commented Jun 20, 2023

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

Ajv options object

const ajv = new Ajv({
  schemas: {
    'foo-schema': FooSchema
  }
})

JSON Schema

const FooSchema: JSONSchemaType<Foo> = {
  $id: 'foo-schema',
  type: "object",
  properties: {foo: {type: "number"}},
  required: ["foo"],
  additionalProperties: false,
}

Sample data

const foo = {
  foo: true
}

Your code

import Ajv, { JSONSchemaType } from 'ajv';

interface Foo {
  foo: number
}

interface Bar {
  foo: boolean
}

const foo: Bar = {
  foo: true
}

const FooSchema: JSONSchemaType<Foo> = {
  $id: 'foo-schema',
  type: "object",
  properties: {foo: {type: "number"}},
  required: ["foo"],
  additionalProperties: false,
}

const ajv = new Ajv({
  schemas: {
    'foo-schema': FooSchema
  }
})



const validate = ajv.getSchema<Foo>('foo-schema')
if (!validate) {
  throw new Error()
}

if (validate(foo)) {
  console.log(foo) // [1]
} else {
  console.log(foo)
}

What results did you expect?
There is a change in the way the validate function narrows the type of its parameter.

Using typescript until 5.0, the type of foo at the bookmark [1] in the above example, matches the type passed as a generic to the getSchema function.

Using typescript 5.1, the type of foo at the bookmark [1] does not change and stay Bar

I have checked the Typescript Changelog but I have not found any lead on what might have changed

Here is a repo with the minimal code to reproduce. If you switch the version of typescript between 5.0 and 5.1, you will notice the change in the narrowing behaviour line 37 of the Validator.ts file.

Are you going to resolve the issue?
I don't think I have the skills to do this but I will check ajv source code.

@Dashron
Copy link

Dashron commented Dec 23, 2023

in case it helps, I came across this issue from a different angle and found some interesting behavior. I've got an example here that works fine.

Key differences:

  • I added as const to the FooSchema.
  • I use compile, not getSchema. I suspect the as const is lost somewhere inside of getSchema
  • I changed the Bar type to accept numbers or booleans, so that we can more easily see that the type guard is working

Now the above example works great, and I hope many people stuck on this can use it to move forward. But in addition to getSchema not working, I'm finding compile doesn't consistently work. I created a separate ticket for that, because my example seems different enough that these might be unrelated.

@tamaroning
Copy link

any update on this?
Type guards always do not work when getSchema is used.

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

No branches or pull requests

4 participants