mongodb Mongoose(& TypeScript)-类型“IEventModel”上不存在属性“_doc”

6ju8rftf  于 12个月前  发布在  Go
关注(0)|答案(6)|浏览(110)

我正在学习一些JavaScript后端编程从我采取的课程。它专注于JavaScript,MongoDB和GraphQL。因为我喜欢让事情对自己更具挑战性,所以我决定在我学习TypeScript的同时,通过用TypeScript完成所有的课程来温习我的TypeScript。
无论如何,我使用的是mongoose的5.5.6版本和@types/mongoose。下面是DB记录类型的接口:

export default interface IEvent {
    _id: any;
    title: string;
    description: string;
    price: number;
    date: string | Date;
}

然后,我创建Mongoose模型如下:

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”不是“result”上的属性。确切的错误是:

error TS2339: Property '_doc' does not exist on type 'IEventModel'.

我不知道我做错了什么。我已经多次查看了文档,似乎我应该在这里拥有所有正确的Mongoose属性。现在我将把这个属性添加到我自己的接口中,只是为了继续本课程,但我更希望在这里帮助确定正确的解决方案。

qpgpyjmq

qpgpyjmq1#

这可能是一个迟来的答案,但服务于所有来寻找这一点。

interface DocumentResult<T> {
    _doc: T;
}

interface IEvent extends DocumentResult<IEvent> {
    _id: any;
    title: string;
    description: string;
    price: number;
    date: string | Date;
}

现在,当你调用(...)._doc时,_doc的类型将是_doc,vscode将能够interpert你的类型。只是一个泛型声明。另外,您可以将其包含在IEvent中,类型为IEvent,而不是创建用于保存该属性的接口。

wlwcrazw

wlwcrazw2#

这是我经常在mongoose旁边使用typescript时所做的事情,首先我们应该为schema和model定义接口:

export interface IDummy {
  something: string;
  somethingElse: string;
}

export interface DummyDocument extends IDummy, mongoose.Document {
  createdAt: Date;
  updatedAt: Date;
  _doc?: any
}

其次,我们应该创建一个schema:

const DummySchema = new mongoose.Schema<DummyDocument>({
  something: String,
  somethingElse: String,
})

最后,我们将使用导出模型模式从文件导出我们的模型作为一个模块:

export const DummyModel = mongoose.model<DummyDocument>

现在问题已经解决了,你不会看到 typescript 错误,我们已经手动附加了_doc到我们的模型与泛型的援助。

t5zmwmid

t5zmwmid3#

interface MongoResult {
  _doc: any
}

export default interface IEvent extends MongoResult {
    _id: any;
    title: string;
    description: string;
    price: number;
    date: string | Date;
}

然后你仍然需要处理将_doc转换回你自己的IEvent.

hmae6n7t

hmae6n7t4#

将类型为any的**_doc**添加到自定义Model界面

interface IUser extends Document {
 ...
 _doc: any
}

一个完整的例子是https://github.com/apotox/express-mongoose-typescript-starter

dwthyt8l

dwthyt8l5#

_doc字段将是一个循环引用。所以一个简单的方法就是简单地做这样的事情。它还通过在子记录中省略自身来避免无限循环引用。不需要接口扩展!

export default interface IEvent {
    _doc: Omit<this,'_doc'>;
}
k10s72fa

k10s72fa6#

由于某些原因,返回类型的结构没有包含在@types/mongoose lib中。因此,每次你想解构返回对象时,你都会得到一个错误,即文档和自定义类型的接口签名中没有定义变量。这应该是一个bug,我猜。
解决方案是返回结果本身,这将自动返回接口(IEvent)中定义的数据,而不包括Meta数据。

...    
try {
    const result = await event.save();
                return result;
            } catch (ex) {
                throw ex;
            }
...

相关问题