Mongoose 和 TypeScript - 类型“事件模型”上不存在属性“_doc”
Posted
技术标签:
【中文标题】Mongoose 和 TypeScript - 类型“事件模型”上不存在属性“_doc”【英文标题】:Mongoose & TypeScript - Property '_doc' does not exist on type 'IEventModel' 【发布时间】:2019-11-05 13:26:03 【问题描述】:我正在通过我正在学习的课程学习一些 javascript 后端编程。它专注于 ExpressJS、MongoDB 和 GraphQL。因为我喜欢让自己的事情更具挑战性,所以我决定在完成所有 TypeScript 课程的同时复习我的 TypeScript。
无论如何,我使用的是 mongoose 和 @types/mongoose 的 5.5.6 版本。这是我的数据库记录类型的界面:
export default interface IEvent
_id: any;
title: string;
description: string;
price: number;
date: string | Date;
然后我像这样创建猫鼬模型:
import Document, Schema, model from 'mongoose';
import IEvent from '../ts-types/Event.type';
export interface IEventModel extends IEvent, Document
const eventSchema: Schema = new Schema(
title:
type: String,
required: true
,
description:
type: String,
required: true
,
price:
type: Number,
required: true
,
date:
type: Date,
required: true
);
export default model<IEventModel>('Event', eventSchema);
最后,我为 GraphQL 突变编写了以下解析器:
createEvent: async (args: ICreateEventArgs): Promise<IEvent> =>
const eventInput = args;
const event = new EventModel(
title: eventInput.title,
description: eventInput.description,
price: +eventInput.price,
date: new Date(eventInput.date)
);
try
const result: IEventModel = await event.save();
return ...result._doc ;
catch (ex)
console.log(ex); // tslint:disable-line no-console
throw ex;
我的问题是 TypeScript 给了我一个错误,即“._doc”不是“结果”的属性。确切的错误是:
error TS2339: Property '_doc' does not exist on type 'IEventModel'.
我不知道我做错了什么。我已经多次查看文档,似乎我应该在这里拥有所有正确的 Mongoose 属性。暂时我将把属性添加到我自己的界面中,只是为了继续课程,但我更希望在这里帮助确定正确的解决方案。
【问题讨论】:
【参考方案1】:interface MongoResult
_doc: any
export default interface IEvent extends MongoResult
_id: any;
title: string;
description: string;
price: number;
date: string | Date;
那么您仍然需要处理将 _doc 转换回您自己的 IEvent...
【讨论】:
【参考方案2】:将类型为 any 的 _doc 添加到您的自定义模型界面
interface IUser extends Document
...
_doc: any
这里有一个完整的例子https://github.com/apotox/express-mongoose-typescript-starter
【讨论】:
【参考方案3】:这可能是一个较晚的答案,但适用于所有搜索此问题的人。
inteface DocumentResult<T>
_doc: T;
interface IEvent extends DocumentResult<IEvent>
_id: any;
title: string;
description: string;
price: number;
date: string | Date;
现在,当您调用 (...)._doc 时,_doc 将属于 _doc 类型,vscode 将能够对您的类型进行干预。只是一个通用的声明。此外,您可以将其包含在具有 IEvent 类型的 IEvent 中,而不是创建用于保存该属性的接口。
【讨论】:
【参考方案4】:当我总是在 mongoose 旁边使用 typescript 时,我会这样做, 首先我们应该为模式和模型定义接口:
export interface IDummy
something: string;
somethingElse: string;
export interface DummyDocument extends IDummy, mongoose.Document
createdAt: Date;
updatedAt: Date;
_doc?: any
第二个我们应该创建模式:
const DummySchema = new mongoose.Schema<DummyDocument>(
something: String,
somethingElse: String,
)
最后我们将使用导出模型模式将我们的模型作为模块从文件中导出:
export const DummyModel = mongoose.model<DummyDocument>
现在问题已经解决,您不会看到打字稿错误,我们已经手动将 _doc 附加到我们的模型中,并在泛型的帮助下使用泛型。
【讨论】:
【参考方案5】:由于某些原因,@types/mongoose lib 中没有包含返回类型的结构。因此,每次您想要解构返回对象时,您都会收到一个错误,即在文档和自定义类型的接口签名中未定义变量。我猜这应该是某种错误。
解决方案是返回结果本身,它会自动返回接口(IEvent)中定义的数据,没有元数据。
...
try
const result = await event.save();
return result;
catch (ex)
throw ex;
...
【讨论】:
以上是关于Mongoose 和 TypeScript - 类型“事件模型”上不存在属性“_doc”的主要内容,如果未能解决你的问题,请参考以下文章
如何在nestjs mongoose typescript中引用嵌套文档
TypeScript 的 Mongoose loadClass 问题
typescript 使用TypeScript和MongoDb的Mongoose示例
typescript 使用TypeScript和MongoDb的Mongoose示例