Динамическое создание схемы вложенных объектов Yup

Для этого "плоского" объекта проверка

const fields = [
  {label: 'Name', name: 'name', validation: yup.string().required()},
  {label: 'City', name: 'city', validation: yup.string().required()},
  {label: 'Phone', name: 'phone'},
]

Я создал createYupSchema функцию, чтобы получить объект схемы Yup из fields.

const createYupSchema = (fields ) => {
  const schema = fields.reduce((schema, field) => {
      return field.validation 
      ? {...schema, [field.name]: field.validation} 
      : schema
  }, {})

  return yup.object().shape(schema)
}

Результатом является объект Yup:

yup.object().shape({
  name: yup.string().required(),
  city: yup.string().required(),
}) 

Но я хотел бы иметь возможность использовать также вложенный объект в fields

const fields = [
  {label: 'Name', name: 'name', validation: yup.string().required()},
  {label: 'Address', name: 'address.city', validation: yup.string().required()},
  {label: 'Phone', name: 'phone'},
]

Итак, объект Yup должен быть:

yup.object().shape({
  name: yup.string().required(),
  address: yup.object().shape({
      city: yup.string().required()
  }),
}) 

Можно ли создать этот тип объекта Yup из fields?


person Webman    schedule 13.09.2019    source источник


Ответы (1)


Я решил свой вопрос. Теперь createYupSchema так работает

const createYupSchema = fields => {
  const schema = fields.reduce((schema, field) => {
    const isObject = field.name.indexOf(".") >= 0;

    if (!field.validation) {
      return schema;
    }

    if (!isObject) {
      return { ...schema, [field.name]: field.validation };
    }

    const reversePath = field.name.split(".").reverse();
    const currNestedObject = reversePath .slice(1).reduce((yupObj, path) => {
        return { [path]: yup.object().shape(yupObj) };
    }, {[reversePath [0]]: field.validation});

    return { ...schema, ...currNestedObject };
  }, {});

  return yup.object().shape(schema);
};
person Webman    schedule 14.09.2019