Closed
Description
Prerequisites
- I have written a descriptive issue title
- I have searched existing issues to ensure the bug has not already been reported
Mongoose version
8.2.2
Node.js version
20
MongoDB server version
5.x
Typescript version (if applicable)
5.2.2
Description
When calling toObject on a populated document (which used a type parameter in populate
) the type structure is lost.
Steps to Reproduce
Based on the example from the docs:
import { Document, model, Schema, Types } from 'mongoose';
// `Parent` represents the object as it is stored in MongoDB
interface Parent {
child?: Types.ObjectId;
name?: string;
}
const ParentModel = model<Parent>(
'Parent',
new Schema({
child: { type: Schema.Types.ObjectId, ref: 'Child' },
name: String
})
);
interface Child {
name: string;
}
const childSchema: Schema = new Schema({ name: String });
const ChildModel = model<Child>('Child', childSchema);
// Populate with `Paths` generic `{ child: Child }` to override `child` path
ParentModel.findOne({})
.populate<{ child: Child }>('child')
.orFail()
.then(doc => {
// Works
const t: string = doc.child.name;
// **** Works not as expected ****
const docObject = doc.toObject();
const t2: string = docObject.child.name; // error - child is not Child
});
Expected Behavior
I'd expect that the passed type information (ie. { child: Child }
) is preserved when calling toObject
.
Not sure if this can be done, so let me add a question: Are there any recommendations for a workaround? We do quite some heavy population in different combinations and I'd ideally like to infer the typings based on the already existing types.
Something like this works, but is quite tedious:
const docObject = doc.toObject<MergeType<Parent, { child: Child }>>();
const t2: string = docObject.child.name;