Search code examples
reactjstypescriptyupunform

React with yup error Type 'undefined' cannot be used as an index type. TS2538


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;

Solution

  • 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.