express-json-validator-middleware: 2.1.0 breaks TS build

2.0.0 works great but once updated to 2.1.0 I got strange errors from ts compiler.

Type '{ type: string; required: string[]; properties: { firstName: { type: string; }; lastName: { type: string; }; email: { type: string; }; phone: { type: string[]; }; password: { type: string; }; participantId: { type: string; }; }; }' is not assignable to type 'ValidateFunction'.
  Type '{ type: string; required: string[]; properties: { firstName: { type: string; }; lastName: { type: string; }; email: { type: string; }; phone: { type: string[]; }; password: { type: string; }; participantId: { type: string; }; }; }' is not assignable to type 'JSONSchema7'.
    Types of property 'type' are incompatible.
      Type 'string' is not assignable to type '"string" | "number" | "boolean" | "object" | "integer" | "null" | "array" | JSONSchema7TypeName[]'.

About this issue

  • Original URL
  • State: closed
  • Created 4 years ago
  • Reactions: 1
  • Comments: 21 (10 by maintainers)

Commits related to this issue

Most upvoted comments

Adding as const did not fix the errors for me.

My error:

Error:(30, 14) TS2322: Type '{ type: string; properties: { mustHaveField: { type: string; }; }; required: string[]; }' is not assignable to type 'ValidateFunction'.
  Type '{ type: string; properties: { mustHaveField: { type: string; }; }; required: string[]; }' is not assignable to type 'JSONSchema7'.
    Types of property 'type' are incompatible.
      Type 'string' is not assignable to type 'JSONSchema7TypeName | JSONSchema7TypeName[]'.

Solution:

const schema: JSONSchema7 = {
  type: 'object',
  properties: {
    mustHaveField: { type: 'boolean' },
  },
  required: ['mustHaveField'],
};

Also updated to the latest json-schema type definition to avoid type mismatch error. At time of writing that’s "@types/json-schema": "^7.0.9",

HTH

I’m planning to merge #89 tomorrow so that I can close this issue and get v2.2.0 released.

Thanks for your help everyone!

@Beraliv I’ve added a section to the README explaining how to define schemas in TypeScript. If you’re still happy to, I’d be very grateful if you could review these changes for accuracy: https://github.com/simonplend/express-json-validator-middleware/pull/89

Sure, I can check it tomorrow

@Beraliv I’ve added a section to the README explaining how to define schemas in TypeScript. If you’re still happy to, I’d be very grateful if you could review these changes for accuracy: https://github.com/simonplend/express-json-validator-middleware/pull/89

@simonplend do you still need help?

Would you mind me tagging you in the PR?

Not at all, I’m fine with it 👍

@Beraliv Thank you so much for this detailed detective work, the thorough explanation, and for all of the examples too. They are really helpful.

I think I understand everything you’ve explained, but I’m going to read it all again with fresh eyes tomorrow.

I’m planning to add a short section to the project README with tips on usage with TypeScript. If you are happy to, I would really appreciate you looking over these documentation changes before I merge them. Would you mind me tagging you in the PR?

@Beraliv That’s great, thank you! It seems similar to the solution which @senorpedro mentioned above.

This raises a couple of questions for me:

  • Why does making object a string literal fix things?
  • Is it preferable to put as const after the object string, or after the whole object itself?

I really appreciate everyone’s help with this issue. I only have a little experience with TypeScript, and I want to make sure I resolve this issue correctly, even if it just means adding a section to the README with some guidance on using this library with TypeScript.

@simonplend You need to use as const to make object a string literal:

It works good here: https://tsplay.dev/WJ96lm

@monooso can you provide a minimal working example in CodeSandbox with json?

However, as I understand, even with "resolveJsonModule": true you will get string, but not the string literal But you can convert *.json to *.ts files with as const and it will work just fine for you

I experienced the same issue, what worked for me was to put as const after the type value, e.g.

{
  type: 'object' as const
 ...
}

unfortunately this meant not being able to use .json files anymore, had to migrate them to TS

I think the advantage of this approach is that TS will complain when a invalid value for type is entered, which it won’t do when explicit type casting to JSONSchema7.

@vacekj I’m having the same problem.

@rmolinamir is correct in that the error is triggered by type: "object". His solution doesn’t make any sense to me, unfortunately.

The strange thing is that passing an object directly to the validate function works. For example:

import { Validator } from 'express-json-validator-middleware'

const validator = new Validator({ allErrors: true })

const mySchema = { type: 'object', properties: {} }

// Passing the schema inline works
validator.validate({ body: { type: 'object', properties: {} } })

// Passing the variable throws an error
validator.validate({ body: mySchema })

// Even expanding the variable throws an error
validator.validate({ body: { ...mySchema } })

I’m completely stumped. Any thoughts?


Update

The following functions as a workaround.

import { JSONSchema7 } from 'json-schema'

validator.validate({ body: mySchema as JSONSchema7 })

sure https://github.com/mmouterde/bugDemo

import { Validator } from 'express-json-validator-middleware';
const UserParamSchemaForUpdate = {
    type: 'object',
    properties: {
        firstName: { type: 'string' }
    },
};
const validator = new Validator({
    allErrors: true,
    format: 'full',
    jsonPointers: true,
});
validator.validate({
    body: UserParamSchemaForUpdate,
});

I will look into it ASAP.