Skip to content

Type declaration for messages option of any.validate() inconsistent with the documentation and actual code #2720

Closed
@kmbt

Description

@kmbt

Context

  • node version: v16.13.1
  • module version with issue: 17.5.0
  • last module version without issue: ?
  • environment (e.g. node, browser, native): node
  • used with (e.g. hapi application, another framework, standalone, ...): standalone
  • any other relevant information:

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

I am trying to supply localized error messages as documented here: https://github.com/sideway/joi/blob/master/API.md#anyvalidatevalue-options

The documentation for options.errors.language states that the messages object is a 'two-dimensional' object:

The value is matched against keys at the root of the messages object, and then the error code as a child key of that

, thus I try to use schema.validate() the following way:

import Joi, { LanguageMessages } from "joi";

const validationMessages = {
  'en': {
    'string.empty': 'XYZ',
  }
}

const schema = Joi.object({
  key: Joi.string()
})

schema.validate({}, {
  errors: {
    language: 'en'
  },
  messages: validationMessages
})

What was the result you got?

A typescript error on messages option:

Type '{ en: { 'string.empty': string; }; }' is not assignable to type 'LanguageMessages'.
  Property ''en'' is incompatible with index signature.
    Type '{ 'string.empty': string; }' is not assignable to type 'string'.ts(2322)

Looking into the library code I have found that the type for messages given here:
https://github.com/sideway/joi/blob/b4dbd59371be9d0fbbaa5f561d5aef929028ad99/lib/index.d.ts#L181-L190
is LanguageMessages which is defined here:
https://github.com/sideway/joi/blob/b4dbd59371be9d0fbbaa5f561d5aef929028ad99/lib/index.d.ts#L29

, which is just a flat object.

What result did you expect?

I would expect, that the required type for messages is declared as one of the following:

  1. Record<string, string | Record<string, string>>
  2. Record<string, Record<string, string>>
  3. Record<string, string> | Record<string, Record<string, string>>

Option 1. seems to most accurately describe the data shape actually accepted as the messages option. It actually seems possible to provide a flat object with just error keys or a mixed one, as such:

const validationMessages : T = {
  'es': {
    'string.empty': 'XYZ',
  },
  'pl': {
    'string.empty': 'KLM',
  },
  'string.empty': 'PQR'
}

, while Option 2. reflects the documentation for validate() best.

Metadata

Metadata

Assignees

Labels

typesTypeScript type definitions

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions