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

Using JSONSchemaType seems a huge build hog #1659

Closed
tommarien opened this issue Jun 23, 2021 · 8 comments
Closed

Using JSONSchemaType seems a huge build hog #1659

tommarien opened this issue Jun 23, 2021 · 8 comments

Comments

@tommarien
Copy link

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

ajv@8.6.0

Your typescript code

import Ajv, { JSONSchemaType } from 'ajv';
import addFormats from 'ajv-formats';

interface UserRequestBody {
  firstName: string;
  lastName: string;
  email: string;
  age?: number;
  address?: string;
  city?: string;
  zip?: string;
}

const ajv = new Ajv({
  coerceTypes: true,
  useDefaults: true,
  removeAdditional: true,
});
addFormats(ajv);

const userValidationSchema: JSONSchemaType<UserRequestBody> = {
  type: 'object',
  properties: {
    firstName: { type: 'string' },
    lastName: { type: 'string' },
    email: { type: 'string', format: 'email' },
    age: { type: 'number', minimum: 1, nullable: true },
    address: { type: 'string', nullable: true },
    city: { type: 'string', nullable: true },
    zip: { type: 'string', nullable: true },
  },
  required: ['firstName', 'lastName', 'email'],
};

const validateUser = ajv.compile(userValidationSchema);

export default validateUser;

Typescript compiler error messages
No compilation issues but build time increases drasticly, from around 1,5 secs to 11 secs

By using --generateTrace i discovered that is was related to UncheckedJSONSchemaType type.

Just changing to

import Ajv from 'ajv';
import addFormats from 'ajv-formats';

interface UserRequestBody {
  firstName: string;
  lastName: string;
  email: string;
  age?: number;
  address?: string;
  city?: string;
  zip?: string;
}

const ajv = new Ajv({
  coerceTypes: true,
  useDefaults: true,
  removeAdditional: true,
});
addFormats(ajv);

const userValidationSchema = {
  type: 'object',
  properties: {
    firstName: { type: 'string' },
    lastName: { type: 'string' },
    email: { type: 'string', format: 'email' },
    age: { type: 'number', minimum: 1, nullable: true },
    address: { type: 'string', nullable: true },
    city: { type: 'string', nullable: true },
    zip: { type: 'string', nullable: true },
  },
  required: ['firstName', 'lastName', 'email'],
};

const validateUser = ajv.compile<UserRequestBody>(userValidationSchema);

export default validateUser;

Describe the change that should be made to address the issue?

What can i do to assist or resolve this issue

Are you going to resolve the issue?
Not sure if i can help 🤷

@epoberezkin
Copy link
Member

Not much can be done about it - everything has a price. JSONSchemaType is a complex type level transformation that converts your data interface to the type that JSON Schema should have. It's purpose is to simplify and speed up schema authoring (via code autocomplete) and to avoid mistakes - so it can save hours of debugging time. Depending on your data interface it can take some time to compile.

The good thing about it is that its completely optional - you can use ajv without using JSONSchemaType if compilation time is more important...

@epoberezkin
Copy link
Member

It might be worth submitting as an issue to TS - there might be some potential to optimise compilation there.

@tommarien
Copy link
Author

@epoberezkin wow, that was closed fast, maybe not advise it as best practice on the ajv site. Other question is there a type which you can use that just does the same as using the `"$schema": "http://json-schema.org/draft-07/schema#" in your json schema?

const scheme: JSONSchema = {};

The problem is was describing impacts everything in a normal typescript oriented build, vscode intellisense is also impacted when using @typescript/es-lint. I am guessing there is something that can be optimised, maybe something recursive. maybe related to microsoft/TypeScript#3496 (comment)

@epoberezkin
Copy link
Member

is there a type which you can use that just does the same as using the `"$schema": "http://json-schema.org/draft-07/schema#" in your json schema?

There is SomeJSONSchema - is it what you are looking for?

@epoberezkin
Copy link
Member

I am guessing there is something that can be optimised, maybe something recursive.

The type indeed has to be recursive, and I don’t see any ways to simplify it - TS is not very optimised for complex type transformations…

@aleccool213
Copy link

This wouldn't be much of an issue if it was just a build time issue but @tommarien is right that it essentially makes your IDE unusable. Users will get put off by this. I have a very powerful Macbook and it slowed down the TS compiler in VS Code to a snail 🐌

@ryanmr
Copy link

ryanmr commented Jun 28, 2021

Hi all,

I added the following validation with ajv ^8.6.0 and ajv-formats ^2.1.0. It has a drastic impact on typescript speed in Visual Studio Code.

const schema: JSONSchemaType<AnExampleIncomingDto> = {
  type: 'object',
  properties: {
    name: { type: 'string', maxLength: 100 },
    email: { type: 'string', format: 'email' },
    about: { type: 'string', maxLength: 1000 },
    startDate: { type: 'string', format: 'date' },
    endDate: { type: 'string', format: 'date' },
    requirements: { type: 'string', maxLength: 1000 },
  },
  required: [
    'name',
    'email',
    'startDate',
    'endDate',
    'requirements',
  ],
  additionalProperties: false,
};

export const validate = ajv.compile(schema);

The validation works great, and build time isn't much a problem since that happens in CI and already can take multiple minutes. Meanwhile, Visual Studio Code, the small validation with typescript above, takes drastically longer to bring up autocompletes and tooltips. Somewhere on the order of between 5 and 25 seconds.

I was surprised by this behavior and did not expect it.

@epoberezkin
Copy link
Member

see #1667 (comment) - looks like it's the issue with TS 4.3+

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