Skip to content

Type definition incorrect for "warning" return type from validateAsync #2927

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

Closed
WVAviator opened this issue Mar 12, 2023 · 2 comments
Closed
Assignees
Labels
support Questions, discussions, and general support types TypeScript type definitions
Milestone

Comments

@WVAviator
Copy link

Support plan

  • is this issue currently blocking your project? no:
  • is this issue affecting a production system? no:

Context

  • node version: 18.12.1
  • module version with issue: 17.8.3
  • last module version without issue: n/a
  • environment (e.g. node, browser, native): node
  • used with (e.g. hapi application, another framework, standalone, ...): standalone
  • any other relevant information: I'd be happy to contribute to a fix for this, just assign me. Thanks for everything!

What are you trying to achieve or the steps to reproduce?

In the type definition for validateAsync, when options include { warnings: true }, the return promise then includes a type of ValidationError[] for the warning. However, the actual value returned appears to be of type ValidationError (or is at least an object with message and details properties), regardless of how many warnings are returned (they are all included in the "details" ValidationErrorItem array, and the error message is a concatenated string of all the warning messages).

To reproduce, run the following code with Node:

import Joi from 'joi';

const warningsIssue = async () => {
  const mySchema = Joi.object({
    a: Joi.any()
      .warning('custom.x', { w: 'world' })
      .messages({ 'custom.x': 'Hello {#w}' }),
    b: Joi.any()
      .warning('custom.y', { w: 'world' })
      .messages({ 'custom.y': 'Hello {#w}' }),
  });

  const myObject = { a: 1, b: '2' };

  try {
    const { warning } = await mySchema.validateAsync(myObject, {
      warnings: true,
    });

    console.log('Warning:', warning);
  } catch (error: any) {
    console.log('Error:', error);
  }
};

warningsIssue();

The logged result will be the following, which is an object where the expected type is an array:

Warning: {
  message: 'Hello world',
  details: [
    {
      message: 'Hello world',
      path: [Array],
      type: 'custom.x',
      context: [Object]
    },
    {
      message: 'Hello world',
      path: [Array],
      type: 'custom.y',
      context: [Object]
    }
  ]
}

Here is the type definition for validateAsync:

        /**
         * Validates a value using the schema and options.
         */
        validateAsync<TOpts extends AsyncValidationOptions>(
          value: any,
          options?: TOpts
        ): Promise<
          TOpts extends { artifacts: true } | { warnings: true }
            ? { value: TSchema } & (TOpts extends { artifacts: true }
            ? { artifacts: Map<any, string[][]> }
            : {}) &
            (TOpts extends { warnings: true }
              ? { warning: ValidationError[] } // actual return is ValidationError
              : {})
            : TSchema
          >;

What was the result you got?

I got a type error when trying to access and iterate over the details property of the resolved value for warning from validateAsync({ warnings: true }).

What result did you expect?

No type errors and a type definition that aligns with the return value

@WVAviator WVAviator added the support Questions, discussions, and general support label Mar 12, 2023
@WVAviator
Copy link
Author

If you need someone to contribute to this, go ahead and assign me and I'll get a PR going for it. Thanks!

@Marsup Marsup added the types TypeScript type definitions label Mar 14, 2023
Marsup added a commit that referenced this issue Mar 14, 2023
@Marsup Marsup self-assigned this Mar 14, 2023
@Marsup Marsup added this to the 17.8.4 milestone Mar 14, 2023
@Marsup
Copy link
Collaborator

Marsup commented Mar 14, 2023

Thanks for the report and for offering your help, I felt it would be easier if I made the fix. It's not exactly a ValidationError as it doesn't inherit from Error, but it shares most of its properties indeed.

@Marsup Marsup closed this as completed Mar 14, 2023
Marsup added a commit that referenced this issue Mar 14, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
support Questions, discussions, and general support types TypeScript type definitions
Projects
None yet
Development

No branches or pull requests

2 participants