动态创建 Yup 嵌套对象模式

Web*_*man 6 javascript yup formik

对于这个“平面”对象验证

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

我创建了createYupSchemafields.

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

  return yup.object().shape(schema)
}
Run Code Online (Sandbox Code Playgroud)

输出是 Yup 对象:

yup.object().shape({
  name: yup.string().required(),
  city: yup.string().required(),
}) 
Run Code Online (Sandbox Code Playgroud)

但我也有可能使用嵌套对象 fields

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

所以 Yup 对象应该是:

yup.object().shape({
  name: yup.string().required(),
  address: yup.object().shape({
      city: yup.string().required()
  }),
}) 
Run Code Online (Sandbox Code Playgroud)

是否可以从创建这种类型的 Yup 对象fields

Web*_*man 5

我解决了我的问题。现在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);
};
Run Code Online (Sandbox Code Playgroud)