Skip to content

Commit

Permalink
Merge pull request #11560 from mohammad0-0ahmad-forks/#11532
Browse files Browse the repository at this point in the history
Fix: Populate query return type.
  • Loading branch information
vkarpov15 authored Mar 27, 2022
2 parents 0ee823d + a955a08 commit c2103cb
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 4 deletions.
32 changes: 31 additions & 1 deletion test/types/populate.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,12 +170,14 @@ function gh11503() {
const User = model<IUser>('friends', userSchema);

User.findOne({}).populate('friends').then(user => {
expectType<Types.ObjectId | undefined>(user?.friends[0]);
if (!user) return;
expectType<Types.ObjectId>(user?.friends[0]);
expectError(user?.friends[0].blocked);
expectError(user?.friends.map(friend => friend.blocked));
});

User.findOne({}).populate<{ friends: Friend[] }>('friends').then(user => {
if (!user) return;
expectAssignable<Friend>(user?.friends[0]);
expectType<boolean>(user?.friends[0].blocked);
const firstFriendBlockedValue = user?.friends.map(friend => friend)[0];
Expand All @@ -197,4 +199,32 @@ function gh11544() {
User.findOne({}).populate({ path: 'friends', strictPopulate: false });
User.findOne({}).populate({ path: 'friends', strictPopulate: true });
User.findOne({}).populate({ path: 'friends', populate: { path: 'someNestedPath', strictPopulate: false } });
}

async function _11532() {
interface IParent {
name: string;
child: Types.ObjectId;
}
interface IChild {
name: string;
}

const parentSchema = new Schema(
{
name: { type: String, required: true },
child: { type: Schema.Types.ObjectId, ref: 'Child', required: true }
});

const parent = model<IParent>('Parent', parentSchema);

const populateQuery = parent.findOne().populate<{ child: IChild }>('child');
const populateResult = await populateQuery;
const leanResult = await populateQuery.lean();

if (!populateResult) return;
expectType<string>(populateResult.child.name);

if (!leanResult) return;
expectType<string>(leanResult.child.name);
}
6 changes: 3 additions & 3 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1471,7 +1471,7 @@ declare module 'mongoose' {

type QueryWithHelpers<ResultType, DocType, THelpers = {}, RawDocType = DocType> = Query<ResultType, DocType, THelpers, RawDocType> & THelpers;

type UnpackedIntersection<T, U> = T extends (infer A)[]
type UnpackedIntersection<T, U> = T extends null ? null : T extends (infer A)[]
? (Omit<A, keyof U> & U)[]
: keyof U extends never
? T
Expand Down Expand Up @@ -1776,8 +1776,8 @@ declare module 'mongoose' {
polygon(path: string, ...coordinatePairs: number[][]): this;

/** Specifies paths which should be populated with other documents. */
populate<Paths = {}>(path: string | string[], select?: string | any, model?: string | Model<any, THelpers>, match?: any): QueryWithHelpers<UnpackedIntersection<ResultType, Paths>, DocType, THelpers, RawDocType>;
populate<Paths = {}>(options: PopulateOptions | (PopulateOptions | string)[]): QueryWithHelpers<UnpackedIntersection<ResultType, Paths>, DocType, THelpers, RawDocType>;
populate<Paths = {}, TRawDocType = UnpackedIntersection<ResultType, Paths>>(path: string | string[], select?: string | any, model?: string | Model<any, THelpers>, match?: any): QueryWithHelpers<TRawDocType, DocType, THelpers, TRawDocType>;
populate<Paths = {}, TRawDocType = UnpackedIntersection<ResultType, Paths>>(options: PopulateOptions | (PopulateOptions | string)[]): QueryWithHelpers<TRawDocType, DocType, THelpers, TRawDocType>;

/** Get/set the current projection (AKA fields). Pass `null` to remove the current projection. */
projection(): ProjectionFields<DocType> | null;
Expand Down

0 comments on commit c2103cb

Please sign in to comment.