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
相关产品推荐
相关产品推荐

