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

如何正确合并两个JOI基础校验schema 解决Schema can only contain plain objects报错

Joi合并多个基础Schema的正确实现方案

Error: Schema can only contain plain objects 报错的核心原因是:baseAddressSchema是Joi的Schema实例,不是普通的字段定义对象,直接使用展开运算符...无法获取其内部的纯对象格式字段配置,传入.keys()方法时就会触发参数类型校验失败。

推荐方案:使用.concat()方法合并Schema

Joi官方提供了concat方法专门用于合并两个同类型的Schema实例,不需要手动提取字段,天然支持规则继承和覆盖,实现代码如下:

export const contactSchema = baseValidationSchema
  // 第一步:合并地址校验Schema的所有规则
  .concat(baseAddressSchema)
  // 第二步:追加当前Schema独有的自定义字段校验规则
  .keys({
    email: validateEmail(),
    firstName: validateName(),
    lastName: validateName(),
    phone: validatePhone(),
    spamFlag: validateBoolean()
  });

注意事项

  • 合并的优先级由调用顺序决定:后合并的Schema规则会覆盖前序Schema的同名字段规则,如果需要自定义字段优先级高于baseAddressSchema的同名字段,保持上面的写法即可;如果需要地址字段优先级更高,可以把.keys()调用移到.concat()前面。
  • 该方法仅支持合并同类型的Schema,比如两个都是Joi.object()类型的Schema,这也是你的业务场景下的默认情况。

特殊场景备选方案:提取Schema字段为纯对象

如果确实需要手动操作字段配置,可以通过.describe()方法获取Schema的结构化描述,再提取字段对象合并,该方案稳定性低于concat,仅推荐特殊场景使用:

// 提取baseAddressSchema的所有字段配置为纯对象
const addressFieldConfig = baseAddressSchema.describe().keys;

export const contactSchema = baseValidationSchema.keys({
  ...addressFieldConfig,
  email: validateEmail(),
  firstName: validateName(),
  lastName: validateName(),
  phone: validatePhone(),
  spamFlag: validateBoolean()
});

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.30 02:06:04