|
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'; |
2 | 2 | // Use the mongodb ObjectId to make instanceof calls possible |
3 | 3 | import { ObjectId } from 'mongodb'; |
4 | 4 | import { expectAssignable, expectError, expectType } from 'tsd'; |
@@ -459,3 +459,96 @@ async function gh14574() { |
459 | 459 | expectType<string>(user.fullName()); |
460 | 460 | expectType<string>(user.friend.fullName()); |
461 | 461 | } |
| 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