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

Mongoose 6/7与Typegoose 10中ObjectId转String报错求助

解决Mongoose 6/7升级后user_id映射的toString类型错误

问题原因

升级到Mongoose 6+后,Typegoose的@prop配置和类型映射逻辑有变化:

  • 原代码中@prop({})未明确指定属性类型,导致Typegoose无法正确将user_id映射为mongoose.Types.ObjectId实例
  • 类型别名定义存在笔误(ExperimentUserSchema应为ExperimentUser),导致TS类型检查失效,运行时属性实际值不符合预期
  • 直接调用document.user_id?.toString()时,若user_id不是合法的ObjectId实例(比如未正确初始化或类型错误),就会触发Function.prototype.toString的this指向错误

解决方案

1. 修正实体类的@prop配置与类型定义

明确指定user_id的类型,并修正类型别名的笔误:

import mongoose from 'mongoose';
import type { DocumentType } from '@typegoose/typegoose';
import { getModelForClass, prop } from '@typegoose/typegoose';

export class ExperimentUser {
  // 明确指定属性类型为mongoose.Types.ObjectId
  @prop({ type: mongoose.Types.ObjectId })
  public user_id?: mongoose.Types.ObjectId;
}

// 修正笔误:将ExperimentUserSchema改为ExperimentUser
export type ExperimentUserDocument = DocumentType<ExperimentUser>;
export const ExperimentUserModel = getModelForClass(ExperimentUser);

2. 安全处理user_id的toString调用

在映射函数中增加类型检查,确保只有ObjectId实例才调用toString:

import { HydratedDocument } from 'mongoose';
import mongoose from 'mongoose';

private map(document: HydratedDocument<ExperimentUser>): ExperimentUserDTO {
  return {
    id: document._id.toString(),
    // 先判断是否为ObjectId实例,再调用toString
    user_id: document.user_id instanceof mongoose.Types.ObjectId 
      ? document.user_id.toString() 
      : undefined
  };
}

3. 优化创建逻辑(可选)

避免向create方法传入undefined属性,减少潜在的类型问题:

import mongoose from 'mongoose';

async create(user_id?: string): Promise<ExperimentUserDTO> {
  const createData: Partial<ExperimentUser> = {};
  if (user_id) {
    createData.user_id = new mongoose.Types.ObjectId(user_id);
  }
  const created_user = await ExperimentUserModel.create(createData);
  // 类方法需用this.map调用
  return this.map(created_user);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 15:38:32