Skip to content

Commit

Permalink
Merge pull request #10494 from juhdanad/lean-populated
Browse files Browse the repository at this point in the history
Make LeanDocument work with PopulatedDoc
  • Loading branch information
vkarpov15 authored Jul 28, 2021
2 parents 0afa2ba + ef1c65e commit fcbadbc
Show file tree
Hide file tree
Showing 3 changed files with 30 additions and 9 deletions.
15 changes: 10 additions & 5 deletions index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2567,13 +2567,18 @@ declare module 'mongoose' {
type LeanArray<T extends unknown[]> = T extends unknown[][] ? LeanArray<T[number]>[] : LeanType<T[number]>[];

export type _LeanDocument<T> = {
[K in keyof T]:
0 extends (1 & T[K]) ? T[K] : // any
T[K] extends unknown[] ? LeanArray<T[K]> : // Array
T[K] extends Document ? LeanDocument<T[K]> : // Subdocument
T[K];
[K in keyof T]: LeanDocumentElement<T[K]>;
};

// Keep this a separate type, to ensure that T is a naked type.
// This way, the conditional type is distributive over union types.
// This is required for PopulatedDoc.
type LeanDocumentElement<T> =
0 extends (1 & T) ? T : // any
T extends unknown[] ? LeanArray<T> : // Array
T extends Document ? LeanDocument<T> : // Subdocument
T;

export type LeanDocument<T> = Omit<_LeanDocument<T>, Exclude<keyof Document, '_id' | 'id' | '__v'> | '$isSingleNested'>;

export type LeanDocumentOrArray<T> = 0 extends (1 & T) ? T :
Expand Down
3 changes: 2 additions & 1 deletion test/typescript/main.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,8 @@ describe('typescript syntax', function() {
if (process.env.D && errors.length) {
console.log(errors);
}
assert.equal(errors.length, 0);
assert.equal(errors.length, 1);
assert.ok(errors[0].messageText.includes('Property \'save\' does not exist'), errors[0].messageText);
});

it('generics', function() {
Expand Down
21 changes: 18 additions & 3 deletions test/typescript/populate.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
import { Schema, model, Document, PopulatedDoc } from 'mongoose';
// Use the mongodb ObjectId to make instanceof calls possible
import { ObjectId } from "mongodb";

interface Child {
name: string;
Expand All @@ -8,7 +10,7 @@ const childSchema: Schema = new Schema({ name: String });
const ChildModel = model<Child>('Child', childSchema);

interface Parent {
child?: PopulatedDoc<Child & Document>,
child?: PopulatedDoc<Child & Document<ObjectId>>,
name?: string
}

Expand All @@ -17,8 +19,21 @@ const ParentModel = model<Parent>('Parent', new Schema({
name: String
}));

ParentModel.findOne({}).populate('child').orFail().then((doc: Parent) => {
useChildDoc(doc.child);
ParentModel.findOne({}).populate('child').orFail().then((doc: Parent & Document) => {
const child = doc.child;
if (child == null || child instanceof ObjectId) {
throw new Error('should be populated');
} else {
useChildDoc(child);
}
const lean = doc.toObject();
const leanChild = lean.child;
if (leanChild == null || leanChild instanceof ObjectId) {
throw new Error('should be populated');
} else {
const name = leanChild.name;
leanChild.save();
}
});

function useChildDoc(child: Child): void {
Expand Down

0 comments on commit fcbadbc

Please sign in to comment.