Search code examples
typescriptexpressexpress-validator

Property 'path' does not exist on type 'ValidationError'. with express-validator 7.0.1


I am trying to access the path field from express-validator 7.0.1. But when I do, I receive an error "Property 'path' does not exist on type 'ValidationError'".:

import express, { Request, Response } from "express";
import { check, validationResult } from "express-validator";

import { save } from "./UserService";

const router = express.Router();
type ValidationResultError = {
  [string: string]: [string];
};

router.post(
  "/api/1.0/users",
  check("username").notEmpty().withMessage("Username cannot be null"),
  check("email").notEmpty().withMessage("E-mail cannot be null"),
  async (req: Request, res: Response) => {
    const errors = validationResult(req);
    if (!errors.isEmpty()) {
      const validationErrors: ValidationResultError = {};      
      errors
        .array()
        .forEach((error) => (validationErrors[error.path] = error.msg)); // error is here
      return res.status(400).send({ validationErrors: validationErrors });
    }
    await save(req.body);
    return res.send({ message: "User Created" });
  }
);

Here is how it is shown in the editor:

enter image description here When I modify the source code where I am iterating over the errors array and log the error object in the console:

...
errors.array().forEach((error) => console.log(error));
...

I am able to see all the objects, which have the path field in the console:

    {
      type: 'field',
      value: null,
      msg: 'Username cannot be null',
      path: 'username',
      location: 'body'
    }

    {
      type: 'field',
      value: null,
      msg: 'E-mail cannot be null',
      path: 'email',
      location: 'body'
    }

But I can only access the msg, and the type field. All the other fields don't work:

enter image description here

I don't know how to fix this.


Solution

  • From the migration-v6-to-v7#Telling error types apart

    The ValidationError type in TypeScript is now a discriminated union.

    It might be necessary to use a switch or if statements to check that you're dealing with the type that you want to format/debug.

    Only the FieldValidationError has the path field.

    type FieldValidationError = {
      type: 'field';
      location: Location;
      path: string;
      value: any;
      msg: any;
    };
    

    Also, take a look ValidationError documentation

    Any of the validation errors. It's possible to determine what the error actually is by looking at its type property

    import express from 'express';
    import { check, validationResult } from 'express-validator';
    
    const router = express.Router();
    type ValidationResultError = {
        [string: string]: [string];
    };
    
    router.post(
        '/api/1.0/users',
        check('username').notEmpty().withMessage('Username cannot be null'),
        check('email').notEmpty().withMessage('E-mail cannot be null'),
        async (req, res) => {
            const errors = validationResult(req);
            if (!errors.isEmpty()) {
                const validationErrors: ValidationResultError = {};
                errors.array().forEach((error) => {
                    if (error.type === 'field') {
                        // error is FieldValidationError 
                        validationErrors[error.path] = error.msg;
                    }
                });
                return res.status(400).send({ validationErrors: validationErrors });
            }
            return res.send({ message: 'User Created' });
        },
    );