TypeScript向Mongoose的ObjectId数组push _id时抛出类型错误
问题根因
报错来自两个层面的问题:
- Schema类型声明错误:定义Schema字段类型时需要使用
mongoose.Schema.Types.ObjectId,你写的mongoose.Types.ObjectId是ObjectId实例的运行时类,不能用于Schema字段类型声明。Mongoose无法识别这个类型配置,就会把数组内的{type: xxx, ref: 'Order'}解析为子文档结构,认为orders数组存储的是包含type、ref两个属性的对象,而非ObjectId引用值,因此校验push操作时抛出类型不匹配错误。 - 业务逻辑错误:你用新创建订单的
_id作为参数查询bike文档,订单和bike是两个独立集合,id互不关联,永远查不到目标bike;另外push完订单id后没有调用save()方法,修改不会持久化到数据库。
修复步骤
1. 修正Schema定义
替换ObjectId的引用来源,确保Mongoose正确识别引用字段类型:
const bikeSchema = new mongoose.Schema({ name: String, model: String, color: String, location: String, rating: String, available: String, orders: [ { type: mongoose.Schema.Types.ObjectId, // 替换为Schema.Types.ObjectId ref: 'Order', }, ], });
如果修改后TS仍有类型提示,可以给模型添加显式泛型声明,明确字段类型:
import mongoose, { Document } from 'mongoose'; // 定义Bike文档类型 interface IBike extends Document { name: string; model: string; color: string; location: string; rating: string; available: string; orders: mongoose.Types.ObjectId[]; // 明确指定orders为ObjectId数组 } // 绑定泛型创建模型 const bikeModel = mongoose.model<IBike>('Bike', bikeSchema);
2. 修正业务代码逻辑
查询bike时使用入参中携带的目标bikeId,修改完成后调用save落库:
async function create(data: any) { try { // 创建订单 const createdOrder = await model.create(data); // 用入参中的bikeId查询关联车辆,不要用订单id查询 const bike = await bikeModel.findById(data.bikeId); if (bike) { bike.orders.push(createdOrder._id); await bike.save(); // 必须调用save持久化修改 } } catch (error: any) { console.log(`[${RESOURCE}:create] controller error:${error}`); throw error; } }
内容的提问来源于stack exchange,提问作者Valeri
相关产品推荐
相关产品推荐

