Mongoose 6.2.3聚合$match阶段使用布尔值报TS类型错误如何解决
Mongoose聚合管道$match阶段使用布尔值报类型错误的原因与解决方法
报错根因
该报错是TypeScript编译阶段的类型校验错误,并非MongoDB运行时不支持布尔值匹配:
- MongoDB原生
$match语法本身完全支持直接传入布尔值作为字段匹配条件,逻辑上不存在问题 - Mongoose 6.0-6.2.x版本内置的TypeScript类型定义存在疏漏,
PipelineStage.Match类型没有将原始布尔值纳入合法的条件值范围,仅识别聚合表达式类型,因此直接写winningAmountClaimed: true会触发Type 'boolean' is not assignable to type 'Expression'报错 - Mongoose 6.x及以上版本已内置类型定义,无需额外安装
@types/mongoose依赖,该依赖安装方式是正确的
相关代码参考
模型定义
const GambitSchema: Schema = new Schema({ _id: { type: String, required: true, default: v4 }, shortCode: { type: String, required: true, default: () => uid(), unique: true, }, question: { type: String }, options: { type: [String], require: true, length: 2 }, correctOption: { type: Number, default: null }, winningMultiple: { type: Number, required: true, default: 1.25 } }) const GambitUserBetSchema: Schema = new Schema({ _id: { type: String, required: true, default: v4 }, discordID: { type: String, required: true }, gambitId: { type: String, required: true }, winningAmountClaimed: { type: Boolean, default: false }, }) export const GambitUserBet = model('GambitUserBet', GambitUserBetSchema) export default model('Gambit', GambitSchema)
触发报错的查询代码
const gambitUser = await GambitUserBet.aggregate([ { $match: { discordID: "1234", winningAmountClaimed: true, }, }, { $lookup: { from: 'gambits', localField: 'gambitId', foreignField: '_id', as: 'gambit', }, }, ])
报错信息
error TS2769: No overload matches this call. Overload 1 of 2, '(pipeline?: PipelineStage[], options?: AggregateOptions, callback?: Callback<any[]>): Aggregate<any[]>', gave the following error. Type 'boolean' is not assignable to type 'Expression'. Overload 2 of 2, '(pipeline: PipelineStage[], callback?: Callback<any[]>): Aggregate<any[]>', gave the following error. Type 'boolean' is not assignable to type 'Expression'.
解决方案
按推荐优先级从高到低可选以下三种方案:
- 升级Mongoose版本到6.3.0及以上,官方已在后续版本修复该类型定义疏漏,升级后原有代码无需任何改动即可通过TS校验
- 使用
$eq操作符改写布尔匹配条件,绕开原始布尔值的类型校验,执行逻辑和直接写布尔值完全一致:
const gambitUser = await GambitUserBet.aggregate([ { $match: { discordID: "1234", winningAmountClaimed: { $eq: true }, }, }, // 后续$lookup阶段逻辑保持不变 ])
- 给
$match条件对象添加类型断言,跳过TS对该对象的严格类型校验,改动量最小:
const gambitUser = await GambitUserBet.aggregate([ { $match: { discordID: "1234", winningAmountClaimed: true, } as Record<string, any>, }, // 后续$lookup阶段逻辑保持不变 ])
补充说明
给出的Schema定义本身没有语法问题,winningAmountClaimed字段的布尔类型定义、默认值配置均符合Mongoose规范,不需要调整模型代码。
内容的提问来源于stack exchange,提问作者Abhay Singh
相关产品推荐
相关产品推荐

