You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Joi校验中with()与without()函数的作用是什么?

Joi中with()和without()函数的作用解析及示例说明

我来给你拆解Joi里with()和without()这两个方法的作用,结合你提供的示例代码详细说明:

1. with():定义字段间的依赖关系

这个方法的核心作用是强制字段间的关联性:当指定的第一个字段存在时,第二个(或多个)字段必须同时存在且符合自身的校验规则。

在你的示例代码里:

.with('username', 'birthyear')

因为username被标记为.required()(必填字段),所以只要请求数据里包含username(这里是必然存在的),就必须同时提供birthyear字段,并且birthyear得符合Joi.number().integer().min(1900).max(2013)的规则。

  • 如果只传username但不传birthyear,校验会直接失败
  • 如果传了birthyear但值不在1900-2013之间,同样校验失败

2. without():定义字段间的互斥关系

这个方法用来禁止两个字段同时出现,确保它们是互斥的——可以只传其中一个,也可以两个都不传,但绝对不能同时存在。

在你的示例代码里:

.without('password', 'access_token')

意思是password和access_token这两个字段不能同时出现在请求数据中:

  • 只传password或者只传access_token,校验可以通过
  • 两个都不传,也符合规则
  • 但如果同时传了password和access_token,校验会直接报错

完整示例代码回顾

const schema = Joi.object().keys({
  username: Joi.string().alphanum().min(3).max(30).required(),
  password: Joi.string().regex(/^[a-zA-Z0-9]{3,30}$/),
  access_token: [Joi.string(), Joi.number()],
  birthyear: Joi.number().integer().min(1900).max(2013),
  email: Joi.string().email()
}).with('username', 'birthyear').without('password', 'access_token');

快速测试场景参考

  • ✅ 合法:{ username: 'john_doe', birthyear: 1990, password: 'pass123' }(满足依赖,且互斥字段只传一个)
  • ✅ 合法:{ username: 'jane_smith', birthyear: 1985, access_token: 'abc123' }(同上)
  • ❌ 非法:{ username: 'bob', password: 'test123' }(缺少必填的birthyear,违反with()规则)
  • ❌ 非法:{ username: 'alice', birthyear: 2000, password: 'pass456', access_token: 789 }(同时传了password和access_token,违反without()规则)

内容的提问来源于stack exchange,提问作者talhaakbar

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:39:54