Skip to content

Commit

Permalink
types(query+populate): apply populate overrides to doc toObject() r…
Browse files Browse the repository at this point in the history
…esult

Fix #14441
  • Loading branch information
vkarpov15 committed Apr 15, 2024
1 parent 78bbcb5 commit a68cc5c
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 2 deletions.
46 changes: 46 additions & 0 deletions test/types/populate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -373,3 +373,49 @@ async function gh13070() {
const doc2 = await Child.populate<{ child: IChild }>(doc, 'child');
const name: string = doc2.child.name;
}

function gh14441() {
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 });
model<Child>('Child', childSchema);

ParentModel.findOne({})
.populate<{ child: Child }>('child')
.orFail()
.then(doc => {
expectType<string>(doc.child.name);
const docObject = doc.toObject();
expectType<string>(docObject.child.name);
});

ParentModel.findOne({})
.populate<{ child: Child }>('child')
.lean()
.orFail()
.then(doc => {
expectType<string>(doc.child.name);
});

ParentModel.find({})
.populate<{ child: Child }>('child')
.orFail()
.then(docs => {
expectType<string>(docs[0]!.child.name);
const docObject = docs[0]!.toObject();
expectType<string>(docObject.child.name);
});
}
16 changes: 14 additions & 2 deletions types/query.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,18 @@ declare module 'mongoose' {
? (ResultType extends any[] ? Require_id<FlattenMaps<RawDocType>>[] : Require_id<FlattenMaps<RawDocType>>)
: ResultType;

type MergePopulatePaths<RawDocType, ResultType, QueryOp, Paths, TQueryHelpers> = QueryOp extends QueryOpThatReturnsDocument
? ResultType extends null
? ResultType
: ResultType extends (infer U)[]
? U extends Document
? HydratedDocument<MergeType<RawDocType, Paths>, Record<string, never>, TQueryHelpers>[]
: (MergeType<U, Paths>)[]
: ResultType extends Document
? HydratedDocument<MergeType<RawDocType, Paths>, Record<string, never>, TQueryHelpers>
: MergeType<ResultType, Paths>
: MergeType<ResultType, Paths>;

class Query<ResultType, DocType, THelpers = {}, RawDocType = DocType, QueryOp = 'find'> implements SessionOperation {
_mongooseOptions: MongooseQueryOptions<DocType>;

Expand Down Expand Up @@ -608,7 +620,7 @@ declare module 'mongoose' {
model?: string | Model<any, THelpers>,
match?: any
): QueryWithHelpers<
UnpackedIntersection<ResultType, Paths>,
MergePopulatePaths<RawDocType, ResultType, QueryOp, Paths, THelpers>,
DocType,
THelpers,
UnpackedIntersection<RawDocType, Paths>,
Expand All @@ -617,7 +629,7 @@ declare module 'mongoose' {
populate<Paths = {}>(
options: PopulateOptions | (PopulateOptions | string)[]
): QueryWithHelpers<
UnpackedIntersection<ResultType, Paths>,
MergePopulatePaths<RawDocType, ResultType, QueryOp, Paths, THelpers>,
DocType,
THelpers,
UnpackedIntersection<RawDocType, Paths>,
Expand Down

0 comments on commit a68cc5c

Please sign in to comment.