reopened: BREAKING CHANGE from 8.7.2: lean query return full mongoose object type for populated doc instead of FlattenMaps #15102
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.9.0
Node.js version
20.10.0
MongoDB server version
6.0.2
Typescript version (if applicable)
5.5.4
Description
I'm reopening this issue because it was closed without resolution. You can find the closed issue at this link.
I'll try to use a simpler example to explain what the bug is:
// child.ts
import {
Connection,
HydratedDocument,
Model,
Schema,
SchemaTypes,
Types,
} from 'mongoose';
export interface IChild {
_id: Types.ObjectId;
name: string;
}
type ChildDocumentOverrides = {};
export interface IChildVirtuals {
id: string;
}
export type ChildInstance = HydratedDocument<
IChild,
ChildDocumentOverrides & IChildVirtuals
>;
type ChildModelType = Model<
IChild,
{},
ChildDocumentOverrides,
IChildVirtuals,
ChildInstance
>;
export default (connection: Connection) => {
const childSchema = new Schema<IChild, ChildModelType>(
{
name: {
type: SchemaTypes.String,
required: true,
trim: true,
},
},
{},
);
return connection.model<IChild, ChildModelType>('Child', childSchema);
};
// parent.ts
import {
Connection,
Document,
HydratedDocument,
Model,
PopulatedDoc,
Schema,
SchemaTypes,
Types,
} from 'mongoose';
import { IChild } from './child';
export interface IParent {
_id: Types.ObjectId;
name: string;
child: PopulatedDoc<Document<Types.ObjectId> & IChild>;
createdAt: Date;
updatedAt: Date;
}
type ParentDocumentOverrides = {};
export interface IParentVirtuals {
id: string;
}
export type ParentInstance = HydratedDocument<
IParent,
ParentDocumentOverrides & IParentVirtuals
>;
type ParentModelType = Model<
IParent,
{},
ParentDocumentOverrides,
IParentVirtuals,
ParentInstance
>;
export default (connection: Connection) => {
const parentSchema = new Schema<IParent, ParentModelType>(
{
name: {
type: SchemaTypes.String,
required: true,
trim: true,
},
child: {
type: SchemaTypes.ObjectId,
ref: 'Child',
required: true,
},
},
{},
);
return connection.model<IParent, ParentModelType>('Parent', parentSchema);
};
My query:
const parent = await Parent.findOne().lean();
If I execute the query in versions prior to 8.7.2, the returned type is FlattenMaps<IParent>
✅:
From version 8.7.2 onwards, the type within the parent for child is Types.ObjectId or an instance of child ❌. However, this is incorrect because I executed a lean query, so child should be Types.ObjectId | FlattenMaps<IChild>
:
In your comment, you suggested updating the code and explicitly setting the type of the variable to be populated. However, if I do not want to populate the variable and use a lean query, the returned type should be FlattenMaps for all PopulatedDoc.
Please, review this situation and the example I provided.
Steps to Reproduce
Execute a lean query (without using "populate") on a model that contains variables of type PopulatedDoc.
Expected Behavior
No response