如何使用 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
属性 上的操作顺序是乱序的。如下:
- 确保数组元素是字符串。
- 如果值为字符串,则将其转换为包含自身的数组。
- 如果单个字符串的数组与正则表达式匹配,则继续。如果没有,报告
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.
中存在的规则
所以每当我收到一个字符串时,我都想将它存储为一个数组。但到目前为止我还没有运气,我试着用 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
属性 上的操作顺序是乱序的。如下:
- 确保数组元素是字符串。
- 如果值为字符串,则将其转换为包含自身的数组。
- 如果单个字符串的数组与正则表达式匹配,则继续。如果没有,报告
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.
中存在的规则