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

TypeScript编写MongoDB聚合报ObjectId无法赋值给Expression错误

报错原因

这个错误是Mongoose TypeScript类型定义的推导偏差导致的,属于类型层面的误报,不代表查询逻辑本身存在运行时错误。
Mongoose对聚合管道$match阶段做了类型重载:既支持传入普通的查询匹配条件,也支持传入聚合表达式。当你直接给字段赋值new ObjectId()实例时,TS没有正确识别这是等值匹配的普通查询值,错误走到了聚合表达式(Expression)的类型校验分支,而ObjectId不属于Expression的合法取值范围,就抛出了类型不匹配的错误。
另外你的TS接口定义存在小问题:使用了大写的String、Number包装对象类型,会干扰Mongoose的Schema类型推导,一定程度上也会提升这类类型误报的概率。

修复方案

你可以任选以下一种方案解决,都不会影响实际查询效果:

  • 直接传入ObjectId对应的字符串值:Mongoose在执行匹配时会根据Schema定义的字段类型,自动把字符串转成ObjectId做匹配,完全兼容现有逻辑,也能绕过类型误判
    $match: {
      user_id: "62aed7171b22341ad759d6f1"
    }
    
  • 显式使用$eq操作符写等值匹配:这种写法下Mongoose的类型定义可以正确识别ObjectId是合法的比较值,不会触发类型错误
    $match: {
      user_id: {
        $eq: new ObjectId("62aed7171b22341ad759d6f1")
      }
    }
    
  • 加类型断言修正推导结果:适合不想调整原有传值写法的场景,既可以用宽松的any断言,也可以用Mongoose自带的Condition类型做更严谨的约束
    // 宽松写法
    $match: {
      user_id: new ObjectId("62aed7171b22341ad759d6f1") as any
    }
    
    // 严谨写法
    import type { Condition } from "mongoose";
    
    $match: {
      user_id: new ObjectId("62aed7171b22341ad759d6f1") as Condition<ObjectId>
    }
    
额外优化建议

把你定义的TS接口里的大写包装类型改成小写的TS原始类型,避免后续出现其他类型推导问题,修正后的接口如下:

import type { ObjectId } from "mongoose";

export interface IToolsNewDonationConditions {
  _id: ObjectId;
  user_id: ObjectId;
  type_of_conditions: string;
  amount: number;
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 10:33:10