Mongoose创建文档函数的返回类型问题(TypeScript)
问题:TypeScript中Mongoose模型返回类型报错
场景重现
项目中有两个核心文件:
myDocument.model.ts
import * as mongoose from 'mongoose'; const DocumentSchema = new mongoose.Schema({ url: String, date: Date, }); export default mongoose.model("Document", DocumentSchema);
repository.ts
import Document from "./myDocument.model"; function addDocument(url:string):Document { let newDoc = new Document(); newDoc.url = url; newDoc.date = new Date(); newDoc.save(); return newDoc; }
尝试给addDocument指定返回类型为Document时,TS编译器抛出错误:
error TS2740: Type 'Document<unknown, {}, { url?: string; date?: Date; }> & { url?: string; date?: Date; } & { _id: ObjectId; }' is missing the following properties from type 'Document': URL, alinkColor, all, anchors, and 250 more.
问题根源
核心是命名冲突:浏览器全局作用域中存在原生Document类型(对应DOM文档对象),TypeScript编译器把你写的返回类型Document识别成了这个全局DOM类型,而非你从myDocument.model.ts导入的Mongoose模型实例类型。
解决方案
方案1:重命名导入的模型
在repository.ts中导入时给模型换个名称,直接规避命名冲突:
import MyDocument from "./myDocument.model"; function addDocument(url:string): MyDocument { let newDoc = new MyDocument(); newDoc.url = url; newDoc.date = new Date(); await newDoc.save(); // 建议添加await,save是异步操作 return newDoc; }
方案2:修改模型文件中的模型名称
从根源避免命名重叠,修改myDocument.model.ts的模型命名:
import * as mongoose from 'mongoose'; const DocumentSchema = new mongoose.Schema({ url: String, date: Date, }); // 使用独特名称,和全局Document区分 export default mongoose.model("MyDocument", DocumentSchema);
之后在repository.ts中导入MyDocument并作为返回类型即可。
方案3:显式提取实例类型(进阶)
若不想修改命名,可通过InstanceType工具类型获取模型的实例类型:
import Document from "./myDocument.model"; // 提取Mongoose模型对应的实例类型 type DocumentInstance = InstanceType<typeof Document>; function addDocument(url:string): DocumentInstance { let newDoc = new Document(); newDoc.url = url; newDoc.date = new Date(); await newDoc.save(); return newDoc; }
额外提示
save()是异步方法,建议将函数改为异步并添加await,避免出现未处理的Promise:
async function addDocument(url:string): Promise<MyDocument> { let newDoc = new MyDocument(); newDoc.url = url; newDoc.date = new Date(); await newDoc.save(); return newDoc; }
内容的提问来源于stack exchange,提问作者Zoltan Hernyak
相关产品推荐
相关产品推荐

