'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:
String
orObjectId
, when passed to acreate()
methodObjectId
when returned from Mongoose- Instance of
ICat
when 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 |