Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mongoose & TypeScript - Property '_doc' does not exist on type 'IEventModel'

I'm learning some JavaScript backend programming from a course I'm taking. It focuses on ExpressJS, MongoDB, and GraphQL. Because I like making things more challenging for myself, I decided to also brush up on my TypeScript while I'm at it by doing all the coursework in TypeScript.

Anyway, so I'm using verison 5.5.6 of mongoose and @types/mongoose. Here is my interface for the type of the DB record:

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

Then I create the Mongoose Model like this:

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);

Lastly, I have written the following resolver for a GraphQL mutation:

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;
            }
        }

My problem is that TypeScript gives me an error that "._doc" is not a property on "result". The exact error is:

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

I can't figure out what I'm doing wrong. I've reviewed the documentation many times and it seems that I should have all the correct Mongoose properties here. For the time being I'm going to add the property to my own interface just to move on with the course, but I'd prefer help with identifying the correct solution here.

like image 931
craigmiller160 Avatar asked Nov 27 '22 13:11

craigmiller160


2 Answers

This might be a late answer but serves for all that come searching this.

inteface DocumentResult<T> {
    _doc: T;
}

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

Now when you call for (...)._doc , _doc will be of type _doc and vscode will be able to interpert your type. Just with a generic declaration. Also instead of creating an interface for holding that property you could include it inside IEvent with the type of IEvent.

like image 161
RageousFoxTrot Avatar answered Nov 29 '22 04:11

RageousFoxTrot


This is something that I do when I always use typescript alongside mongoose, first things first we should define interfaces for the schema and model:

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

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

second we should create out schema:

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

finally we are going to use export model pattern for exporting our model as a module from file:

export const DummyModel = mongoose.model<DummyDocument>

Now the problem has fixed and you are not going to see the typescript error, we have manually attached the _doc to our model with generics that the aid of generics.

like image 42
Emad Baqeri Avatar answered Nov 29 '22 04:11

Emad Baqeri