0

I'm using yup to invalidate the forms, when they are invalidated I want this function to return the errors, but it always gives an error in validationErrors[error.path], it gets Type 'undefined' cannot be used as an index type

import { ValidationError } from 'yup';

interface Errors {
  [key: string]: string;
}

export default function getValidationErrors(err: ValidationError): Errors {
  const validationErrors: Errors = {};

  err.inner.forEach(error => {
    validationErrors[error.path] = error.message;
  });

  return validationErrors;
}


----------


Console error: 

    Type 'undefined' cannot be used as an index type.  TS2538
    11 |   err.inner.forEach((error) => {
  > 12 |     validationErrors[error.path] = error.message;
       |                      ^
    13 |   });
    14 |
    15 |   return validationErrors;
Colgate
  • 15
  • 5

1 Answers1

0

The issue here is that ValidationError's path field is declared as optional:

export default class ValidationError extends Error {
  value: any;
  path?: string; // path?: string | undefined
  type?: string;
  errors: string[];

  params?: Params;

  inner: ValidationError[];
...

That means that even when it's present on the error object it's value can (from typescript's point of view) be undefined.

So before using error.path as a computed index value you have to check that it's not undefined. You either check it as supposed:

  err.inner.forEach(error => {
    if (typeof error.path !== 'undefined') {
      validationErrors[error.path] = error.message;
    }
  });

Or if you're absolutely sure it may never be undefined you can just type assert it with non-null assertion operator !:

  err.inner.forEach(error => {
    validationErrors[error.path!] = error.message;
  });

But keep in mind that with type assertion if your suggestion was wrong you'll get validationErrors.undefined field in your error object.

aleksxor
  • 7,535
  • 1
  • 22
  • 27