Skip to content

Commit 8a0f581

Browse files
authored
Merge pull request Automattic#15132 from Automattic/vkarpov15/Automatticgh-15111
types(model+query): avoid stripping out virtuals when calling populate with paths generic
2 parents 0bf4563 + e3c8756 commit 8a0f581

File tree

3 files changed

+190
-97
lines changed

3 files changed

+190
-97
lines changed

test/types/populate.test.ts

Lines changed: 94 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import mongoose, { Schema, model, Document, PopulatedDoc, Types, HydratedDocument, SchemaTypeOptions } from 'mongoose';
1+
import mongoose, { Schema, model, Document, PopulatedDoc, Types, HydratedDocument, SchemaTypeOptions, Model } from 'mongoose';
22
// Use the mongodb ObjectId to make instanceof calls possible
33
import { ObjectId } from 'mongodb';
44
import { expectAssignable, expectError, expectType } from 'tsd';
@@ -459,3 +459,96 @@ async function gh14574() {
459459
expectType<string>(user.fullName());
460460
expectType<string>(user.friend.fullName());
461461
}
462+
463+
async function gh15111() {
464+
interface IChild {
465+
_id: Types.ObjectId;
466+
name: string;
467+
}
468+
469+
type ChildDocumentOverrides = {};
470+
471+
interface IChildVirtuals {
472+
id: string;
473+
}
474+
475+
type ChildInstance = HydratedDocument<
476+
IChild,
477+
ChildDocumentOverrides & IChildVirtuals
478+
>;
479+
480+
type ChildModelType = Model<
481+
IChild,
482+
{},
483+
ChildDocumentOverrides,
484+
IChildVirtuals,
485+
ChildInstance
486+
>;
487+
const childSchema = new Schema<IChild, ChildModelType>(
488+
{
489+
name: {
490+
type: 'String',
491+
required: true,
492+
trim: true
493+
}
494+
}
495+
);
496+
const ChildModel = mongoose.model<IChild, ChildModelType>('Child', childSchema);
497+
498+
interface IParent {
499+
_id: Types.ObjectId;
500+
name: string;
501+
surname: string;
502+
child: PopulatedDoc<Document<Types.ObjectId> & IChild>;
503+
}
504+
505+
type ParentDocumentOverrides = {};
506+
507+
interface IParentVirtuals {
508+
id: string;
509+
fullName: string;
510+
}
511+
512+
type ParentInstance = HydratedDocument<
513+
IParent,
514+
ParentDocumentOverrides & IParentVirtuals
515+
>;
516+
517+
type ParentModelType = Model<
518+
IParent,
519+
{},
520+
ParentDocumentOverrides,
521+
IParentVirtuals,
522+
ParentInstance
523+
>;
524+
const parentSchema = new Schema<IParent, ParentModelType>(
525+
{
526+
name: {
527+
type: 'String',
528+
required: true,
529+
trim: true
530+
},
531+
surname: {
532+
type: 'String',
533+
required: true,
534+
trim: true
535+
},
536+
child: {
537+
type: 'ObjectId',
538+
ref: 'Child',
539+
required: true
540+
}
541+
}
542+
);
543+
544+
parentSchema.virtual('fullName').get(function() {
545+
return `${this.name} ${this.surname}`;
546+
});
547+
548+
const ParentModel = mongoose.model<IParent, ParentModelType>('Parent', parentSchema);
549+
550+
const parents = await ParentModel.find().populate<{ child: ChildInstance }>(
551+
'child'
552+
);
553+
expectType<string>(parents[0].fullName);
554+
}

0 commit comments

Comments
 (0)