TypeScript中通过条件常量设置Mongoose查询函数报错解决
解决Mongoose提取Model方法调用时的"缺少model作为this"错误
需求是实现一个函数:根据输入ID检查数据库中是否存在对应条目,存在则更新该条目,不存在则创建新条目。尝试将Mongoose的updateOne或create方法直接赋值给常量后调用时,触发错误:
"MongooseError:
Model.create()cannot run without a model asthis"
错误原因
Mongoose的Model类方法(如create、updateOne)内部依赖this指向当前的Model实例,直接将方法提取赋值给变量时,this的绑定关系会丢失,导致方法无法找到对应的Model上下文,从而抛出错误。
1. 初始可用但存在代码重复的实现
通过if-else分支完成了功能,但成功/失败的处理逻辑存在重复:
export async function dbUpdateWishlist(wl: wishlistDBType): Promise<BoolTuple> { let response; if ( (await WishlistModel.exists({ discordIdentifier: wl.discordIdentifier, })) !== null ) { // 存在则更新 response = await WishlistModel.updateOne(wl) .then(() => { return [true, 'DB save successful']; }) .catch((err: Error) => { console.log('DB save failed ', err); return [false, 'DB save failed']; }); } else { // 不存在则创建新条目 response = await WishlistModel.create(wl) .then(() => { return [true, 'DB save successful']; }) .catch((err: Error) => { console.log('DB save failed ', err); return [false, 'DB save failed']; }); } return response as BoolTuple; }
2. 尝试简化但报错的代码
直接提取updateOne/create方法赋值给常量,因this绑定丢失触发错误:
export async function dbUpdateWishlist(wl: wishlistDBType): Promise<BoolTuple> { const queryFn = (await WishlistModel.exists({ discordIdentifier: wl.discordIdentifier, })) !== null ? WishlistModel.updateOne : WishlistModel.create; const response = await queryFn(wl) .then(() => { return [true, 'DB save successful']; }) .catch((err: Error) => { console.log('DB save failed ', err); return [false, 'DB save failed']; }); return response as BoolTuple; }
3. 用bind修复后的优化实现
通过bind(WishlistModel)为方法绑定正确的this上下文,同时改用try/catch统一处理成功/失败逻辑,消除代码重复:
export async function dbUpdateWishlist(wl: wishlistDBType): Promise<BoolTuple> { const queryFn = (await WishlistModel.exists({ discordIdentifier: wl.discordIdentifier, })) !== null ? WishlistModel.updateOne.bind(WishlistModel) : WishlistModel.create.bind(WishlistModel); try { await queryFn(wl); return [true, 'DB save successful']; } catch (err) { console.log('DB save failed ', err); return [false, 'DB save failed']; } }
内容的提问来源于stack exchange,提问作者justaprogrammer2
相关产品推荐
相关产品推荐

