javascripttypescriptmongodbmongoosemongoose-schema

Extends mongoose schema with methods - typescript compatible way


I found that the way mongoose suggest to add additional methods to a schema - is not compatible with the typeScript:

import * as m from 'mongoose'

const MySchema = new m.Schema({ deletedAt: Date  });

MySchema.methods.myDelete = function() { this.deletedAt = new Date(); }
MySchema.method('myUndelete', function() { this.deletedAt = null; });


const MyModel = m.model('MyCollection', MySchema);

let myInstance = new MyModel();
myInstance.myDelete();
myInstance.myUndelete();

the typescript compiler says

error TS2339: Property 'myDelete' does not exist on type 'Document<unknown, {}, { deletedAt?: Date; }> & Omit<{ deletedAt?: Date; } & { _id: ObjectId; }, never>'.

error TS2339: Property 'myUndelete' does not exist on type 'Document<unknown, {}, { deletedAt?: Date; }> & Omit<{ deletedAt?: Date; } & { _id: ObjectId; }, never>'.

How to achieve adding new methods to the Schema and get recognized by typescript compiler at the same time? Any idea?


Solution

  • Follow the Statics and Methods in TypeScript documentation.

    E.g.("mongoose": "^7.3.1")

    import * as m from 'mongoose';
    
    interface MyDocument {
        deletedAt?: Date;
    }
    
    interface MyDocumentMethods {
        myDelete(): void;
        myUndelete(): void;
    }
    
    type ModelType = m.Model<MyDocument, {}, MyDocumentMethods>;
    
    const MySchema = new m.Schema<MyDocument>({ deletedAt: Date });
    
    MySchema.methods.myDelete = function () {
        this.deletedAt = new Date();
    };
    MySchema.method('myUndelete', function () {
        this.deletedAt = null;
    });
    
    const MyModel = m.model<MyDocument, ModelType>('MyCollection', MySchema);
    
    let myInstance = new MyModel();
    myInstance.myDelete();
    myInstance.myUndelete();
    myInstance.deletedAt; // ok