Tengo tipos de objetos que tienen una propiedad de 'traducciones' donde los campos que se pueden traducir a diferentes idiomas se pasan a la propiedad 'lang' específica, como puede ver en el esquema a continuación.
Siempre se requiere una traducción al inglés y el resto de los idiomas son opcionales, puedo lograr esto configurando .default(undefined) en los idiomas opcionales.
Cuando un idioma está presente y falla la validación de sus campos internos, el error siempre se asocia al campo en sí ('nombre' en este caso). Se espera este comportamiento.
Lo que más quiero lograr y no sé cómo es mostrar un error cuando la propiedad 'traducciones' 'en' no está presente con un mensaje como '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-]+$)(?:[az]{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) }) })Creo que debería considerar usar un diccionario de configuración regional personalizado. Lo que le permite personalizar los mensajes predeterminados utilizados por Yup, cuando no se proporciona ningún mensaje con una prueba de validación. Si falta algún mensaje en el diccionario personalizado, el mensaje de error será el de Yup. También proporcionó soporte multilingüe.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'] }); Si no puede obtener lo que está buscando con solo eso, intente combinarlo con yup.lazy que crea un esquema que se evalúa en el momento de la validación/emisión. Esto también se puede anidar dentro de su esquema de objeto. https://github.com/jquense/yup#yuplazyvalue-any--schema-lazy
aquí tienes una idea de lo que puedes hacer:
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 } })Bueno, el problema al validar objetos anidados es que por defecto van a objetos vacíos {}, por eso pasa la validación y entra en la validación interna.
Entonces, la solución es hacer que todos los objetos .default(undefined) esa manera podemos agregar más requisitos a la validación del objeto en sí, en este caso haciéndolo obligatorio.
Así que la solución fue tan simple como eso:
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-]+$)(?:[az]{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.'), })