Skip to content

Commit

Permalink
Merge pull request #11769 from taxilian/feature/tsLeanMissingDocId
Browse files Browse the repository at this point in the history
Feature/ts lean missing doc fixes #11761 without killing LeanDocument
  • Loading branch information
vkarpov15 committed May 5, 2022
2 parents d4cd838 + 0fa0611 commit 16e5714
Show file tree
Hide file tree
Showing 3 changed files with 78 additions and 6 deletions.
72 changes: 72 additions & 0 deletions test/types/lean.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,32 @@ function gh10345() {
})();
}

async function gh11761() {
const thingSchema = new Schema<{ name: string }>({
name: Schema.Types.String
});

const ThingModel = model('Thing', thingSchema);

{
// make sure _id has been added to the type
const { _id, ...thing1 } = (await ThingModel.create({ name: 'thing1' })).toObject();
expectType<Types.ObjectId>(_id);

console.log({ _id, thing1 });
}
// stretch goal, make sure lean works as well

const foundDoc = await ThingModel.findOne().lean().limit(1).exec();
{
if (!foundDoc) {
return; // Tell TS that it isn't null
}
const { _id, ...thing2 } = foundDoc;
expectType<Types.ObjectId>(foundDoc._id);
}
}

async function gh11118(): Promise<void> {
interface User {
name: string;
Expand Down Expand Up @@ -162,3 +188,49 @@ async function getBaseDocumentTypeFromModel(): Promise<void> {

const b = a.toJSON();
}


async function _11767() {
interface Question {
text: string;
answers: Types.Array<string>;
correct: number;
}
const QuestionSchema = new Schema<Question>({
text: String,
answers: [String],
correct: Number
});
interface Exam {
element: string;
dateTaken: Date;
questions: Types.DocumentArray<Question>;
}
const ExamSchema = new Schema<Exam>({
element: String,
dateTaken: Date,
questions: [QuestionSchema]
});

const ExamModel = model<Exam>('Exam', ExamSchema);

const examFound = await ExamModel.findOne().lean().exec();
if (!examFound) return;

// Had to comment some of these active checks out

// $pop shouldn't be there, because questions should no longer be a mongoose array
// expectError<Function>(examFound.questions.$pop);
// popoulated shouldn't be on the question doc because it shouldn't
// be a mongoose subdocument anymore
// expectError(examFound.questions[0]!.populated);
expectType<string[]>(examFound.questions[0].answers);

const examFound2 = await ExamModel.findOne().exec();
if (!examFound2) return;
const examFound2Obj = examFound2.toObject();

// expectError(examFound2Obj.questions.$pop);
// expectError(examFound2Obj.questions[0].populated);
expectType<string[]>(examFound2Obj.questions[0].answers);
}
8 changes: 4 additions & 4 deletions types/document.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -221,11 +221,11 @@ declare module 'mongoose' {
set(value: any): this;

/** The return value of this method is used in calls to JSON.stringify(doc). */
toJSON<T = DocType>(options?: ToObjectOptions & { flattenMaps?: true }): FlattenMaps<LeanDocument<T>>;
toJSON<T = DocType>(options: ToObjectOptions & { flattenMaps: false }): LeanDocument<T>;
toJSON<T = LeanDocument<DocType>>(options?: ToObjectOptions & { flattenMaps?: true }): FlattenMaps<T>;
toJSON<T = LeanDocument<DocType>>(options: ToObjectOptions & { flattenMaps: false }): T;

/** Converts this document into a plain-old JavaScript object ([POJO](https://masteringjs.io/tutorials/fundamentals/pojo)). */
toObject<T = DocType>(options?: ToObjectOptions): LeanDocument<T>;
toObject<T = LeanDocument<DocType>>(options?: ToObjectOptions): Require_id<T>;

/** Clears the modified state on the specified path. */
unmarkModified(path: string): void;
Expand All @@ -247,4 +247,4 @@ declare module 'mongoose' {
validateSync(options: { pathsToSkip?: pathsToSkip, [k: string]: any }): Error.ValidationError | null;
validateSync(pathsToValidate?: pathsToValidate, options?: AnyObject): Error.ValidationError | null;
}
}
}
4 changes: 2 additions & 2 deletions types/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2272,8 +2272,8 @@ declare module 'mongoose' {
T;

export type LeanDocumentOrArrayWithRawType<T, RawDocType> = 0 extends (1 & T) ? T :
T extends unknown[] ? RawDocType[] :
T extends Document ? RawDocType :
T extends unknown[] ? LeanDocument<RawDocType>[] :
T extends Document ? LeanDocument<RawDocType> :
T;

export class SchemaType<T = any> {
Expand Down

0 comments on commit 16e5714

Please sign in to comment.