lubegasimon
lubegasimon

Reputation: 31

Typescript seems to not fully support $data option for const validation

I am attempting to use AJV's $data reference to validate that the password and confirmPassword fields in the request body are equal. But typescript errors with;

...

Types of property 'const' are incompatible.
                    Type '{ $data: string; }' is not assignable to type 'string'.
...

I have tried https://stackoverflow.com/a/75910266/12239489 (silences the type error but doesn't solve the underlying problem - ajv compiles the schema as though const validation was absent), and https://stackoverflow.com/a/71098197/12239489, but they all seem not to work for me.

I have also tried to define a keyword using the addKeyword method, but all in vain also.

ajv.addKeyword({
  keyword: "matchPassword",
  type: "string",
  schemaType: "boolean",
  // FIXME: Don't use any type
  validate: (schema: any, data: any, parentSchema: any, parentData: any): any => {
      return schema ? parentData.password === data : true;
  },
  errors: false
})

...

const userSchema: JSONSchemaType<User> = {
  type: "object",
  properties: {
    /* Note: "username" is a custom format, see ../validates */
    username: { type: "string", format: "username" },
    email: { type: "string", format: "email" },
    password: { type: "string", minLength: 5, maxLength: 256 },
    confirmPassword: {
      type: "string",
      passwordMatch: true
    },
  },

...

Below is my userSchema.ts file

import { JSONSchemaType } from "ajv";

interface User {
  username: string;
  email: string;
  password: string;
  confirmPassword: string;
}

const userSchema: JSONSchemaType<User> = {
  type: "object",
  properties: {
    /* Note: "username" is a custom format, see ../validates */
    username: { type: "string", format: "username" },
    email: { type: "string", format: "email" },
    password: { type: "string", minLength: 5, maxLength: 256 },
    confirmPassword: {
      type: "string",
      const: { $data: "1/password" }
    },
  },
  required: ["username", "email", "password", "confirmPassword"],

  additionalProperties: false,
  errorMessage: {
    properties: {
      username:
        "Username must be 5-10 characters long and can only contain letters, numbers, and underscores",
      password: "Password must NOT have fewer than 5 characters",
      confirmPassword: "Passwords do not match",
    },
  },
};

export default userSchema;

Upvotes: 1

Views: 44

Answers (0)

Related Questions