如何用Yup验证数组包含两个指定的不同特定值?
解决Yup数组验证必须包含两个特定不重复值的问题
这个坑我之前踩过!你现在的写法确实只能保证数组里的元素是foo或bar,并且长度固定为2,但没法限制这两个元素必须是各出现一次的foo和bar,所以像['foo', 'foo']这种重复值自然就钻空子通过了。
正确的做法:用test方法自定义验证逻辑
Yup提供了test方法让我们写自定义的验证规则,刚好可以用来解决这个场景。这里有两种靠谱的实现思路:
思路1:直接检查数组是否同时包含两个目标值
这种写法直观易懂,适合简单场景:
Yup.array() .test( 'must-contain-foo-and-bar', // 验证规则的唯一标识(用于错误提示映射) '数组必须同时包含foo和bar两个值', // 错误提示文本 (value) => { // 先判断数组是否存在且长度为2 if (!value || value.length !== 2) return false; // 检查是否同时包含foo和bar return value.includes('foo') && value.includes('bar'); } )
思路2:用Set检查唯一性+包含目标值
如果以后需要扩展到更多不重复值的场景,这种写法更灵活:
Yup.array() .test( 'unique-foo-bar-only', '数组必须包含且仅包含foo和bar各一次', (value) => { if (!value) return false; const uniqueItems = new Set(value); // 两个条件:1. 去重后只有2个值;2. 这两个值刚好是foo和bar return uniqueItems.size === 2 && uniqueItems.has('foo') && uniqueItems.has('bar'); } )
为什么之前的写法失效?
再回头看你原来的代码:
Yup.array() .of(Yup.mixed().oneOf(['foo', 'bar'])) .min(2) .max(2)
.of(...)只是限制了数组里每个元素都属于['foo','bar']这个集合,但不关心元素是否重复;.min(2).max(2)只是固定了数组长度,但没要求两个元素必须是不同的目标值。
所以重复的元素自然能通过验证啦~
内容的提问来源于stack exchange,提问作者Jeroen Knol
相关产品推荐
相关产品推荐

