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

NestJS中@Prop设为ObjectId时API启动失败,设为string正常

NestJS操作MongoDB时@Prop设为ObjectId导致API启动失败的原因解析

问题现象

在NestJS中使用Mongoose定义Schema时,将@Prop的字段类型设置为直接从mongoose导入的ObjectId时,API无法正常启动;将类型改为mongoose.Types.ObjectId后,API恢复正常加载。

错误代码示例

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

export type FriendRequestDocument = FriendRequest & Document;

@Schema({collection: "friendRequests"})
export class FriendRequest {
  @Prop()
  author: ObjectId;

  @Prop()
  friend_id: ObjectId;

  @Prop()
  request_at: Date;
}

export const FriendRequestSchema = SchemaFactory.createForClass(FriendRequest);

修复后的代码

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

export type FriendRequestDocument = FriendRequest & Document;

@Schema({collection: "friendRequests"})
export class FriendRequest {
  @Prop()
  author: mongoose.Types.ObjectId;

  @Prop()
  friend_id: mongoose.Types.ObjectId;

  @Prop()
  request_at: Date;
}

export const FriendRequestSchema = SchemaFactory.createForClass(FriendRequest);

原因解析

  1. 类型与运行时构造函数的区别:从mongoose直接导入的ObjectId是TypeScript的类型别名,仅用于编译时的类型检查,在运行时会被完全擦除,不存在实际的对象或构造函数。
  2. SchemaFactory的运行时依赖:NestJS的SchemaFactory.createForClass方法在解析Schema类时,需要读取字段的运行时类型信息来生成对应的MongoDB Schema规则。如果字段类型是仅编译时存在的类型别名,SchemaFactory无法识别该类型,进而抛出类型解析错误,导致API启动失败。
  3. mongoose.Types.ObjectId的作用:mongoose.Types.ObjectId是Mongoose提供的运行时构造函数,SchemaFactory可以正确识别它,并将字段映射为MongoDB的ObjectId类型,因此能正常生成Schema并启动API。

可选优化方案

如果希望在类型声明时使用更简洁的ObjectId类型别名,同时保证运行时解析正常,可以显式在@Prop装饰器中指定类型:

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

export type FriendRequestDocument = FriendRequest & Document;

@Schema({collection: "friendRequests"})
export class FriendRequest {
  @Prop({ type: mongoose.Types.ObjectId })
  author: ObjectId;

  @Prop({ type: mongoose.Types.ObjectId })
  friend_id: ObjectId;

  @Prop()
  request_at: Date;
}

export const FriendRequestSchema = SchemaFactory.createForClass(FriendRequest);

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 11:01:00