Mongoose 和 TypeScript - 类型“IEventModel”上不存在属性“_doc”

use*_*059 10 mongoose mongodb typescript

我正在从我正在学习的课程中学习一些 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;
}
Run Code Online (Sandbox Code Playgroud)

然后我像这样创建 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);
Run Code Online (Sandbox Code Playgroud)

最后,我为 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;
            }
        }
Run Code Online (Sandbox Code Playgroud)

我的问题是 TypeScript 给我一个错误,指出“._doc”不是“结果”的属性。确切的错误是:

error TS2339: Property '_doc' does not exist on type 'IEventModel'.
Run Code Online (Sandbox Code Playgroud)

我不明白我做错了什么。我已经多次查看文档,似乎我应该在这里拥有所有正确的 Mongoose 属性。目前,我将将该属性添加到我自己的界面中,以便继续课程,但我更希望在此处帮助您确定正确的解决方案。

小智 5

这可能是一个迟到的答案,但适用于所有搜索此问题的人。

interface DocumentResult<T> {
    _doc: T;
}

interface IEvent extends DocumentResult<IEvent> {
    _id: any;
    title: string;
    description: string;
    price: number;
    date: string | Date;
}
Run Code Online (Sandbox Code Playgroud)

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


小智 -2

由于某些原因,返回类型的结构未包含在 @types/mongoose lib 中。因此,每次您想要解构返回对象时,您都会收到一个错误,指出该变量未在文档和自定义类型的接口签名中定义。我猜这应该是某种错误。

解决方案是返回结果本身,它将自动返回接口(IEvent)中定义的数据,而无需元数据。

...    
try {
    const result = await event.save();
                return result;
            } catch (ex) {
                throw ex;
            }
...
Run Code Online (Sandbox Code Playgroud)