如何验证对象 属性 是必需的?
How to validate that an object property is required?
我有具有 'translations' 属性 的对象类型,其中可以将可以翻译成不同语言的字段传递到特定的 'lang' 属性请参阅下面的架构。
始终需要英语翻译,其余语言是可选的,我可以通过将 .default(undefined)
设置为可选语言来实现。
当存在一种语言且对其内部字段的验证失败时,错误始终与字段本身相关联(在本例中为 'name')。此行为是预期的。
我还想实现什么,我不知道如何在 'translations' 属性 'en' 不存在时显示错误消息,如 [=13] =].
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)
})
})
我认为您应该考虑使用自定义语言环境字典。当验证测试没有提供任何消息时,它允许您自定义 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
结合使用,这会创建一个在 validation/cast 时评估的模式。这也可以嵌套在您的对象模式中。 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
}
})
嗯,验证嵌套对象时的问题是它们默认为空对象{},因此它通过了验证并进入了内部验证。
然后解决方案是制作所有对象 .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.'),
})
我有具有 'translations' 属性 的对象类型,其中可以将可以翻译成不同语言的字段传递到特定的 'lang' 属性请参阅下面的架构。
始终需要英语翻译,其余语言是可选的,我可以通过将 .default(undefined)
设置为可选语言来实现。
当存在一种语言且对其内部字段的验证失败时,错误始终与字段本身相关联(在本例中为 'name')。此行为是预期的。
我还想实现什么,我不知道如何在 'translations' 属性 'en' 不存在时显示错误消息,如 [=13] =].
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)
})
})
我认为您应该考虑使用自定义语言环境字典。当验证测试没有提供任何消息时,它允许您自定义 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
结合使用,这会创建一个在 validation/cast 时评估的模式。这也可以嵌套在您的对象模式中。 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
}
})
嗯,验证嵌套对象时的问题是它们默认为空对象{},因此它通过了验证并进入了内部验证。
然后解决方案是制作所有对象 .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.'),
})