简体   繁体   English

如何验证是否需要 object 属性?

[英]How to validate that an object property is required?

I have object types that have a 'translations' property where the fields that can be translated into different languages are passed into the specific 'lang' property as you can see in the schema below.我有 object 类型,它们具有“翻译”属性,其中可以翻译成不同语言的字段被传递到特定的“语言”属性中,如下面的架构所示。

An English translation is always required and the rest of the languages are optional, I can achieve this by setting .default(undefined) to the optional languages.始终需要英文翻译,并且语言的 rest 是可选的,我可以通过将.default(undefined)设置为可选语言来实现这一点。

When a language is present and the validation for its inner fields fails, the error is always associated to the field itself ('name' in this case).当存在一种语言并且对其内部字段的验证失败时,错误总是与字段本身相关联(在这种情况下为“名称”)。 This behaviour is expected.这种行为是预期的。

What I else want to achieve and I don't know how is to show an error when the 'translations' property 'en' is not present with a message like 'An English translation is required' .我还想实现什么,但我不知道如何在 'translations' 属性 'en' 不存在时显示错误,并显示类似'An English translation is required'类的消息。

const categoryTranslationsSchema = object({
    name: string()
        .min(3, 'Must have at least 3 characters.')
        .max(16, 'Cannot be longer than 16 characteres.')
        .required('Must provide a name.')
})

const categorySchema = object({
    slug: string()
        .min(3, 'Must have at least 3 characters.')
        .max(16, 'Cannot be longer than 16 characteres.')
        .lowercase()
        .trim()
        .matches(/^(?![0-9-]+$)(?:[a-z]{2,}-?|[0-9]-?)+(?<!-)$/gm, 'Must start with a letter and can'
            + ' only contain letters, numbers or dashes (no more than one consecutive).')
        .required('The slug is required.'),
    translations: object({
        en: categoryTranslationsSchema,
        es: categoryTranslationsSchema
            .default(undefined),
        de: categoryTranslationsSchema
            .default(undefined)
    })
})

I think you should look into using a custom locale dictionary.我认为您应该考虑使用自定义语言环境字典。 Which allows you to customize the default messages used by Yup, when no message is provided with a validation test.当验证测试没有提供消息时,它允许您自定义 Yup 使用的默认消息。 If any message is missing in the custom dictionary the error message will default to Yup's one.如果自定义字典中缺少任何消息,则错误消息将默认为 Yup 的错误消息。 It also provided enables multi-language support.它还提供了多语言支持。 https://github.com/jquense/yup#using-a-custom-locale-dictionary https://github.com/jquense/yup#using-a-custom-locale-dictionary

import { setLocale } from 'yup';

setLocale({
  mixed: {
    default: 'Não é válido',
  },
  number: {
    min: 'Deve ser maior que ${min}',
  },
});

// now use Yup schemas AFTER you defined your custom dictionary
let schema = yup.object().shape({
  name: yup.string(),
  age: yup.number().min(18),
});

schema.validate({ name: 'jimmy', age: 11 }).catch(function (err) {
  err.name; // => 'ValidationError'
  err.errors; // => ['Deve ser maior que 18']
});

If you can't get what you're looking for with just that try combining it with yup.lazy which creates a schema that is evaluated at validation/cast time.如果你不能得到你正在寻找的东西,请尝试将它与yup.lazy结合起来,它会创建一个在验证/强制转换时评估的模式。 This can be nested inside your object schema as well.这也可以嵌套在您的 object 架构中。https://github.com/jquense/yup#yuplazyvalue-any--schema-lazyhttps://github.com/jquense/yup#yuplazyvalue-any--schema-lazy

here is an idea of what you can do:这是您可以做什么的想法:

translations: Yup.lazy(value => {
      switch (typeof value) {
        case 'object':
          return Yup.object(); // schema for object
        case 'string':
          return Yup.string().min(MIN_DESC_LENGTH).max(_MAX_NAME_LENGTH); // schema for string
        default:
          return Yup.mixed(); // here you can decide what is the default
      }
      })

Well, the problem when validating nested object is that they default to empty objects {}, for that reason it passes the validation and enters the inner validation.好吧,验证嵌套 object 时的问题是它们默认为空对象 {},因此它通过验证并进入内部验证。

The solution is then making all objects .default(undefined) that way we can add more requirements to the object validation itself, in this case making it required.然后解决方案将所有对象.default(undefined) ,这样我们就可以向 object 验证本身添加更多要求,在这种情况下使其成为必需。

So the solution was as simple as that:所以解决方案就这么简单:

const categorySchema = object({
    slug: string()
        .min(3, 'Must have at least 3 characters.')
        .max(16, 'Cannot be longer than 16 characteres.')
        .lowercase()
        .trim()
        .matches(/^(?![0-9-]+$)(?:[a-z]{2,}-?|[0-9]-?)+(?<!-)$/gm, 'Must start with a letter and can'
            + ' only contain letters, numbers or dashes (no more than one consecutive).')
        .required('The slug is required.'),
    translations: object({
        en: categoryTranslationsSchema
            .default(undefined)
            .required('An English translation must be provided.'),
        zh: categoryTranslationsSchema
            .default(undefined)
    }).default(undefined)
        .required('Translations must be defined.'),
})

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM