【问题标题】:How to validate that an object property is required?如何验证是否需要对象属性?
【发布时间】:2022-01-01 19:00:51
【问题描述】:

我的对象类型具有“翻译”属性,其中可以翻译成不同语言的字段被传递到特定的“语言”属性中,如下面的架构所示。

始终需要英文翻译,其余语言是可选的,我可以通过将.default(undefined) 设置为可选语言来实现这一点。

当存在一种语言并且对其内部字段的验证失败时,错误总是与字段本身相关联(在本例中为“名称”)。这种行为是意料之中的。

我还想实现但我不知道如何在“翻译”属性“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)
    })
})

【问题讨论】:

    标签: javascript validation yup


    【解决方案1】:

    我认为您应该考虑使用自定义语言环境字典。当验证测试未提供任何消息时,它允许您自定义 Yup 使用的默认消息。如果自定义字典中缺少任何消息,则错误消息将默认为 Yup 的错误消息。它还提供了多语言支持。 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']
    });
    

    如果您无法获得所需的内容,请尝试将其与 yup.lazy 结合使用,后者会创建一个在验证/强制转换时评估的架构。这也可以嵌套在您的对象模式中。 https://github.com/jquense/yup#yuplazyvalue-any--schema-lazy

    这里是你可以做什么的想法:

    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
          }
          })
    

    【讨论】:

    • 感谢您指出为消息创建语言环境的可能性,我会仔细研究一下,但这不是我正在寻找的解决方案。我会用解决方案回答我自己的问题。
    • @giorgiline 了解。我担心我可能没有完全理解您的要求,因此提供了一些额外的信息。希望这些信息将来有用。
    【解决方案2】:

    嗯,验证嵌套对象时的问题是它们默认为空对象{},因此它通过验证并进入内部验证。

    然后解决方案是让所有对象.default(undefined) 这样我们就可以向对象验证本身添加更多要求,在这种情况下使其成为必需。

    所以解决方案就这么简单:

    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.'),
    })
    

    【讨论】:

      猜你喜欢
      • 2021-04-24
      • 2022-10-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-01-24
      • 2021-11-20
      • 2019-10-01
      • 1970-01-01
      相关资源
      最近更新 更多