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

如何在TypeScript、NestJS的Schema中为字段设置多类型(数组/对象)

Mongoose Schema字段设置多类型并启用MongoDB校验

要实现单个字段支持多类型、数组字段支持多类型元素,同时让MongoDB通过Mongoose完成数据校验,按以下方式调整代码即可:

1. 正确定义子Schema

用@Schema装饰的子类必须通过SchemaFactory.createForClass转换成Schema实例,才能在父Schema中作为类型引用,否则Mongoose无法识别其结构规则。

2. 单个字段支持多类型

在@Prop配置中,通过type属性传入包含多个子Schema的数组,同时添加自定义校验器确保输入结构符合任一子Schema的规则,结合全局的validateBeforeSave: true开启自动校验。

3. 数组字段支持多类型元素

数组元素要支持多类型的话,用mongoose.Schema.Types.Mixed作为基础类型,再配合自定义校验器遍历每个元素,验证其是否符合任一子Schema的结构。

完整示例代码

import { Schema, Prop, SchemaFactory, Document } from '@nestjs/mongoose';
import mongoose from 'mongoose';

@Schema({ validateBeforeSave: true, _id: false })
class Example1 {
  @Prop({ required: true })
  a: string;

  @Prop({ required: true })
  b: number;
}

@Schema({ validateBeforeSave: true, _id: false })
class Example2 {
  @Prop({ required: true })
  a: string;

  @Prop({ required: true })
  b: number;
}

// 将子类转换为Schema实例
const Example1Schema = SchemaFactory.createForClass(Example1);
const Example2Schema = SchemaFactory.createForClass(Example2);

// 数组元素校验器:验证每个元素是否符合Example1或Example2结构
const validateMixedArrayElements = (value: any[]) => {
  return value.every(item => {
    try {
      Example1Schema.validateSync(item);
      return true;
    } catch {
      try {
        Example2Schema.validateSync(item);
        return true;
      } catch {
        return false;
      }
    }
  });
};

@Schema({ collection: 'user', validateBeforeSave: true, timestamps: true })
export class User extends Document {
  // 单个字段:支持Example1或Example2类型
  @Prop({ 
    type: [Example1Schema, Example2Schema],
    required: true,
    validate: {
      validator: (value: any) => {
        try {
          Example1Schema.validateSync(value);
          return true;
        } catch {
          try {
            Example2Schema.validateSync(value);
            return true;
          } catch {
            return false;
          }
        }
      },
      message: 'firstProp结构不符合Example1或Example2规则'
    }
  })
  firstProp: Example1 | Example2;

  // 数组字段:元素支持Example1或Example2类型
  @Prop({ 
    type: [mongoose.Schema.Types.Mixed],
    required: true,
    validate: {
      validator: validateMixedArrayElements,
      message: 'secondProp中存在不符合Example1或Example2规则的元素'
    }
  })
  secondProp: (Example1 | Example2)[];
}

export const UserSchema = SchemaFactory.createForClass(User);

关键说明

  • 子Schema实例是Mongoose识别结构的核心,直接引用类无法触发校验逻辑
  • 自定义校验器通过validateSync方法验证数据合法性,确保只有符合任一子规则的数据能存入MongoDB
  • 全局开启validateBeforeSave: true会在数据保存前自动执行校验,无需手动触发

内容的提问来源于stack exchange,提问作者Amir Mohammad Beheshti

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.11 06:01:01