Mongoose结合TypeScript后静态方法findByFacebookId失效求助
Mongoose静态方法findByFacebookId在TypeScript中无响应的问题排查与解决
看起来你遇到的问题挺典型的——JS里好好的静态方法,转TypeScript就罢工了,连回调都不执行,Promise一直pending。我帮你梳理下几个关键问题和修复方案:
首先,最显眼的低级错误:方法名不匹配
你在Schema里定义的静态方法是findByFacebookId,但调用的时候写的是PersonsModel.findByFId(payload.id)——这俩名字根本对不上啊!如果这是你写代码时的笔误,那先把调用的方法名改成findByFacebookId再说,不然调用一个不存在的方法,结果肯定不对。
TypeScript类型缺失导致的上下文问题
你用model<any>("Persons", PersonsSchema)导出Model,这会让TypeScript完全丢失这个Model的类型信息,包括你添加的静态方法。这种情况下,TS无法正确推断this的指向,可能导致_self.findOne根本没有正确触发数据库查询,自然Promise就一直pending了。
冗余的Promise封装
Mongoose从4.x版本开始就原生支持Promise了,findOne本身就会返回一个Promise,你完全没必要手动再包一层。手动封装不仅多此一举,还可能因为_self的类型不明确,导致内部的回调永远得不到执行。
修复后的完整代码
我给你调整成符合TypeScript规范的写法,同时解决上述问题:
1. 定义类型接口,完善类型约束
import { Document, Schema, Model, model } from "mongoose"; // 定义Person文档的结构接口,继承Document interface IPerson extends Document { fbToken?: string; fbId: number; name?: string; } // 定义包含自定义静态方法的Model接口 interface IPersonModel extends Model<IPerson> { findByFacebookId(id: number): Promise<IPerson | null>; } // 创建Schema时指定泛型为IPerson const PersonsSchema = new Schema<IPerson>({ fbToken: String, fbId: Number, name: String }); // 实现静态方法,直接返回findOne的Promise,不用手动封装 PersonsSchema.statics.findByFacebookId = function(this: IPersonModel, id: number) { return this.findOne({ fbId: id }); } // 导出Model时同时指定文档类型和Model类型 export default model<IPerson, IPersonModel>("Persons", PersonsSchema);
2. 修正调用代码的方法名
getPersonInfo(data) { return FbRestServices.getUserInfo(data.access_token).then((payload) => { // 调用正确的方法名findByFacebookId return PersonsModel.findByFacebookId(payload.id); }); }
额外检查点
如果改完还是不行,你可以确认下Mongoose的数据库连接是否正常——TS接入后如果连接代码有变动,比如异步初始化没处理好,也会导致所有数据库操作挂起。不过你说JS下正常,这个概率比较低,但还是可以排查下。
内容的提问来源于stack exchange,提问作者Nemus
相关产品推荐
相关产品推荐

