Skip to content

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

@WVAviator

Description

@WVAviator

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

Metadata

Metadata

Assignees

Labels

supportQuestions, discussions, and general supporttypesTypeScript type definitions

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions