'Using Mongoose and Typescript, what type should be used for a ref field of an interface?
I am using mongoose and Typescript, and I am wanting to know what type, or types, I should be using for a reference field, when creating an interface? Consider the following two related interfaces:
interface ICat {
name: string,
colour: string,
}
interface ICatDB extends ICat, Document {};
interface IMouse {
name: string,
colour: string,
chasedBy: /* ... */
}
interface IMouseDB extends IMouse, Document {};
And the schemas and models that use them:
let cat = new Schema({
name: String,
colour: String,
});
mongoose.model<ICatDB>('Cat', cat);
let mouse = new Schema({
name: String,
colour: String,
chasedBy: { type: Schema.Types.ObjectId, ref: 'Cat' }
});
mongoose.model<IMouseDB>('Mouse', mouse);
For the chasedBy field we need to consider that it can take values in three forms:
StringorObjectId, when passed to acreate()methodObjectIdwhen returned from Mongoose- Instance of
ICatwhen returned from Mongoose, usingpopulate()
Is there a way that we can specify the types the interface can support, without having to resort to using any?
BTW we separated IMouse and IMouseDB, since Typescript wanted all the fields for Document filled out every time we created a new IMouse object, so this was a work around.
Solution 1:[1]
At least for version 5.x you could use this: https://mongoosejs.com/docs/5.x/docs/typescript/populate.html
import { PopulatedDoc } from 'mongoose';
import ICat from './ICat';
interface IMouse {
name: string,
colour: string,
chasedBy: PopulatedDoc<ICat>
}
The docs in 6.x shows different approach:
https://mongoosejs.com/docs/typescript/populate.html
like this:
MouseModel.findOne({}).populate<{chasedBy: ICat}>('chasedBy');
Solution 2:[2]
Lacking any alternative answer, I went with:
import { ObjectID } from 'mongodb';
import ICat from './ICat';
interface IMouse {
name: string,
colour: string,
chasedBy: string | ObjectID | ICat
}
This describes the type variants for the 'chasedBy' property. As to whether this is the recommended approach, I can't say.
Solution 3:[3]
Mongoose 6.x
Mongoose offers type declarations in mongoose.Types
interface Mouse { // important: don't use I in front of the name and don't extend Document
chasedBy: mongoose.Types.ObjectId
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | |
| Solution 2 | Andre M |
| Solution 3 | winklerrr |
