Marcin Kapusta
Marcin Kapusta

Reputation: 5396

Mongoose Schema with Typescript - Design errors

I have two problems defining schema using mongoose and typescript. Here is my code:

import { Document, Schema, Model, model} from "mongoose";

export interface IApplication {
    id: number;
    name: string;
    virtualProperty: string;
}

interface IApplicationModel extends Document, IApplication {} //Problem 1

let ApplicationSchema: Schema = new Schema({
    id: { type: Number, required: true, index: true, unique: true},
    name: { type: String, required: true, trim: true },
});
ApplicationSchema.virtual('virtualProperty').get(function () {
    return `${this.id}-${this.name}/`; // Problem 2
});
export const IApplication: Model<IApplicationModel> = model<IApplicationModel>("Application", ApplicationSchema);

First of all:

interface IApplicationModel extends Document, IApplication {}

The Typescript is telling me that:

error TS2320: Interface 'IApplicationModel' cannot simultaneously extend types 'Document' and 'IApplication'. Named property 'id' of types 'Document' and 'IApplication' are not identical.

So how to change definition of id property?

The Error is:

error TS2683: 'this' implicitly has type 'any' because it does not have a type annotation.

How to define type of this?

Upvotes: 0

Views: 1171

Answers (2)

Roy
Roy

Reputation: 11

for problem 2: just declare this as any : .get(function (this: any) {}); fix it

Upvotes: 0

Matt McCutchen
Matt McCutchen

Reputation: 30929

Problem #1: Since IApplicationModel extends interfaces Document and IApplication that declare the id property with different types (any and number respectively), TypeScript does not know whether the id property of IApplicationModel should be of type any or number. You can fix this by redeclaring the id property in IApplicationModel with the desired type. (Why are you declaring a separate IApplication interface rather than just declaring IApplicationModel that extends Document with all your properties?)

Problem #2: Just declare the this special parameter to the function as shown below.

import { Document, Schema, Model, model} from "mongoose";

export interface IApplication {
    id: number;
    name: string;
    virtualProperty: string;
}

interface IApplicationModel extends Document, IApplication {
    id: number;
}

let ApplicationSchema: Schema = new Schema({
    id: { type: Number, required: true, index: true, unique: true},
    name: { type: String, required: true, trim: true },
});
ApplicationSchema.virtual('virtualProperty').get(function (this: IApplicationModel) {
    return `${this.id}-${this.name}/`;
});
export const IApplication: Model<IApplicationModel> = model<IApplicationModel>("Application", ApplicationSchema);

Upvotes: 0

Related Questions