diff --git a/test/types/document.test.ts b/test/types/document.test.ts index 84451edf0f..685410eafc 100644 --- a/test/types/document.test.ts +++ b/test/types/document.test.ts @@ -359,3 +359,19 @@ function gh13738() { expectType(person.get('dob')); expectType<{ theme: string; alerts: { sms: boolean } }>(person.get('settings')); } + +async function gh12959() { + const subdocSchema = new Schema({ foo: { type: 'string', required: true } }); + + const schema = new Schema({ + subdocArray: { type: [subdocSchema], required: true } + }); + + const Model = model('test', schema); + + const doc = await Model.findById('id').orFail(); + expectType(doc._id); + expectType(doc.__v); + + expectError(doc.subdocArray[0].__v); +} diff --git a/types/document.d.ts b/types/document.d.ts index 5557269783..7bc140461e 100644 --- a/types/document.d.ts +++ b/types/document.d.ts @@ -24,9 +24,6 @@ declare module 'mongoose' { /** This documents _id. */ _id: T; - /** This documents __v. */ - __v?: any; - /** Assert that a given path or paths is populated. Throws an error if not populated. */ $assertPopulated(path: string | string[], values?: Partial): Omit & Paths; diff --git a/types/index.d.ts b/types/index.d.ts index 02c975a4eb..3ec72ac281 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -138,6 +138,10 @@ declare module 'mongoose' { ? IfAny> : T & { _id: Types.ObjectId }; + export type Default__v = T extends { __v?: infer U } + ? T + : T & { __v?: number }; + /** Helper type for getting the hydrated document type from the raw document type. The hydrated document type is what `new MyModel()` returns. */ export type HydratedDocument< DocType, @@ -147,12 +151,12 @@ declare module 'mongoose' { DocType, any, TOverrides extends Record ? - Document & Require_id : + Document & Default__v> : IfAny< TOverrides, - Document & Require_id, + Document & Default__v>, Document & MergeType< - Require_id, + Default__v>, TOverrides > >