From a68cc5c4b723639e019e9a986b3abde97027e353 Mon Sep 17 00:00:00 2001 From: Valeri Karpov Date: Mon, 15 Apr 2024 12:59:30 -0400 Subject: [PATCH] types(query+populate): apply populate overrides to doc `toObject()` result Fix #14441 --- test/types/populate.test.ts | 46 +++++++++++++++++++++++++++++++++++++ types/query.d.ts | 16 +++++++++++-- 2 files changed, 60 insertions(+), 2 deletions(-) diff --git a/test/types/populate.test.ts b/test/types/populate.test.ts index c846e7b346e..fe9afa4ef84 100644 --- a/test/types/populate.test.ts +++ b/test/types/populate.test.ts @@ -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', + new Schema({ + child: { type: Schema.Types.ObjectId, ref: 'Child' }, + name: String + }) + ); + + interface Child { + name: string; + } + const childSchema: Schema = new Schema({ name: String }); + model('Child', childSchema); + + ParentModel.findOne({}) + .populate<{ child: Child }>('child') + .orFail() + .then(doc => { + expectType(doc.child.name); + const docObject = doc.toObject(); + expectType(docObject.child.name); + }); + + ParentModel.findOne({}) + .populate<{ child: Child }>('child') + .lean() + .orFail() + .then(doc => { + expectType(doc.child.name); + }); + + ParentModel.find({}) + .populate<{ child: Child }>('child') + .orFail() + .then(docs => { + expectType(docs[0]!.child.name); + const docObject = docs[0]!.toObject(); + expectType(docObject.child.name); + }); +} diff --git a/types/query.d.ts b/types/query.d.ts index 1e97ad6331d..71e3a03ec24 100644 --- a/types/query.d.ts +++ b/types/query.d.ts @@ -205,6 +205,18 @@ declare module 'mongoose' { ? (ResultType extends any[] ? Require_id>[] : Require_id>) : ResultType; + type MergePopulatePaths = QueryOp extends QueryOpThatReturnsDocument + ? ResultType extends null + ? ResultType + : ResultType extends (infer U)[] + ? U extends Document + ? HydratedDocument, Record, TQueryHelpers>[] + : (MergeType)[] + : ResultType extends Document + ? HydratedDocument, Record, TQueryHelpers> + : MergeType + : MergeType; + class Query implements SessionOperation { _mongooseOptions: MongooseQueryOptions; @@ -608,7 +620,7 @@ declare module 'mongoose' { model?: string | Model, match?: any ): QueryWithHelpers< - UnpackedIntersection, + MergePopulatePaths, DocType, THelpers, UnpackedIntersection, @@ -617,7 +629,7 @@ declare module 'mongoose' { populate( options: PopulateOptions | (PopulateOptions | string)[] ): QueryWithHelpers< - UnpackedIntersection, + MergePopulatePaths, DocType, THelpers, UnpackedIntersection,