如何在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
相关产品推荐
相关产品推荐

