如何使用 Yup 将字符串转换为数组

How to cast a string into an array using Yup

所以每当我收到一个字符串时,我都想将它存储为一个数组。但到目前为止我还没有运气,我试着用 cast 和 transform 来做。我只是需要一些清晰度来让事情顺利进行。

transform和cast是一回事吗?如何使用 Yup 将字符串转换为数组?

const schema = yup.object().shape({
        types: yup
           .array('type must be an array.')
           .of(
                yup
                   .string('the array must contains only strings.')
                   .transform(value =>
                      typeof value === 'string' || value instanceof 'string'
                           ? [value]
                           : value,
                   )
                   .matches(/(writer|artist)/, null),
           )
           .min(1, 'Need to provide at least one type')
           .max(2, 'Can not provide more than two types'),
        name: yup
           .string('name must be a string.')
           .min(3, 'too short'),
      
    });

let obj = {
      name: 'Kentarou Kishima',
      types: 'artist',
}
//returns ValidationError
obj = schema.cast(obj, { stripUnknown: true });

//trying to just validate results in the same error
schema
        .validate(obj)
        .then(() => {     
              
            next();
        })
        .catch(function (e) {
            console.log(e);
            return something;
        });

ValidationError:类型必须是 array 类型,但最终值为:null(从值 "artist" 转换)

编辑: 顺便说一句,我修正了小错字。 好吧,我删除了 matches 行,它一直返回相同的错误。所以现在我在想,因为它接收的是一个字符串而不是一个数组,当它进入转换函数时,它将搜索要转换的数组项,但是有 none 因为它有一个字符串。所以很可能转换函数应该与 array() 并排而不是在它里面。

代码现在看起来像这样,但无论有没有匹配(),我仍然收到错误:

.array('types must be an array.')
        .of(
            yup
                .string('the array must contains only strings.')
                .matches(/(^writer$|^artist$)/) //I improved the regex pattern                
        )
        .transform(value =>
            typeof value === 'string' || value instanceof String
                ? [value]
                : value,
        )
        .min(1, 'Need to provide at least one type')
        .max(2, 'Can not provide more than two types'),

为了让事情更清楚,这些是我期望的输入类型:

let obj = {
      name: 'Kentarou Kishima',
      types: 'artist', //should cast
      types: ['artist'], //should pass
      types: ['artist', 'writer'], //should pass

      types: '', //should reject
      types: ['something'], //should reject
      types: ['artist', 'something', 'writer'], //should reject
      types: ['artist', 'artist'], // should reject, but i will put a test() later on.  

}

types 属性 上的操作顺序是乱序的。如下:

  1. 确保数组元素是字符串。
  2. 如果值为字符串,则将其转换为包含自身的数组。
  3. 如果单个字符串的数组与正则表达式匹配,则继续。如果没有,报告 null.

如果您真的想要一个 single-element 数组的数组,那么您可以保留转换,但您需要将 matches() 移动到 transform() 上方,因为数组transform() 的结果永远不会匹配正则表达式,因此 matches() 总是 returns 你的 null.

const schema = yup.object().shape({
        types: yup
           .array('type must be an array.')
           .of(
                yup
                   .string('the array must contains only strings.')
                   .matches(/(writer|artist)/, null)
                   .transform(value =>
                      typeof value === 'string' || myVar instanceof 'string'
                           ? [value]
                           : value,
                   ),
           )
           .min(1, 'Need to provide at least one type')
           .max(2, 'Can not provide more than two types'),
        name: yup
           .string('name must be a string.')
           .min(3, 'too short'),
      
    });

在翻阅文档后我找到了答案。在这种情况下使用 ensure() 函数就足够了,基本上它会将任何不是数组的东西放入数组中。之后,matches() 函数将拒绝任何不遵循正则表达式模式的内容。

yup
        .array('types must be an array.')        
        .of(
            yup
                .string('the array must contains only strings.')
                .matches(/(^writer$|^artist$)/)                
        )
        .ensure()
        .min(1, 'Need to provide at least one type')
        .max(2, 'Can not provide more than two types'),

编辑: 只是一个免责声明,启用 min(1) 的方式,即使没有 required(),也总是需要这个 属性,即使在对象中指定 notRequired() 也不行诀窍。

这是 yup 中的一个已知问题 https://github.com/jquense/yup/issues/1267

在我的例子中,我的 POST(所有必需的)和 PUT(至少一个必需的)请求需要这个验证器,在 POST 请求中,我按原样使用它,在PUT 请求我动态添加规则检查 req.body.

中存在的规则