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);
原因解析
- 类型与运行时构造函数的区别:从
mongoose直接导入的ObjectId是TypeScript的类型别名,仅用于编译时的类型检查,在运行时会被完全擦除,不存在实际的对象或构造函数。 - SchemaFactory的运行时依赖:NestJS的
SchemaFactory.createForClass方法在解析Schema类时,需要读取字段的运行时类型信息来生成对应的MongoDB Schema规则。如果字段类型是仅编译时存在的类型别名,SchemaFactory无法识别该类型,进而抛出类型解析错误,导致API启动失败。 - 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
相关产品推荐
相关产品推荐

