Skip to content

Commit e1d3bfa

Browse files
authored
Merge pull request #13963 from Automattic/vkarpov15/gh-13878
fix(document): allow calling `$model()` with no args for TypeScript
2 parents a1d2bf9 + 46a6ecc commit e1d3bfa

File tree

4 files changed

+43
-14
lines changed

4 files changed

+43
-14
lines changed

lib/model.js

Lines changed: 19 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1060,40 +1060,45 @@ Model.prototype.$__deleteOne = function $__deleteOne(options, cb) {
10601060
};
10611061

10621062
/**
1063-
* Returns another Model instance.
1063+
* Returns the model instance used to create this document if no `name` specified.
1064+
* If `name` specified, returns the model with the given `name`.
10641065
*
10651066
* #### Example:
10661067
*
1067-
* const doc = new Tank;
1068-
* await doc.model('User').findById(id);
1068+
* const doc = new Tank({});
1069+
* doc.$model() === Tank; // true
1070+
* await doc.$model('User').findById(id);
10691071
*
1070-
* @param {String} name model name
1071-
* @method model
1072+
* @param {String} [name] model name
1073+
* @method $model
10721074
* @api public
10731075
* @return {Model}
10741076
*/
10751077

1076-
Model.prototype.model = function model(name) {
1078+
Model.prototype.$model = function $model(name) {
1079+
if (arguments.length === 0) {
1080+
return this.constructor;
1081+
}
10771082
return this[modelDbSymbol].model(name);
10781083
};
10791084

10801085
/**
1081-
* Returns another Model instance.
1086+
* Returns the model instance used to create this document if no `name` specified.
1087+
* If `name` specified, returns the model with the given `name`.
10821088
*
10831089
* #### Example:
10841090
*
1085-
* const doc = new Tank;
1086-
* await doc.model('User').findById(id);
1091+
* const doc = new Tank({});
1092+
* doc.$model() === Tank; // true
1093+
* await doc.$model('User').findById(id);
10871094
*
1088-
* @param {String} name model name
1089-
* @method $model
1095+
* @param {String} [name] model name
1096+
* @method model
10901097
* @api public
10911098
* @return {Model}
10921099
*/
10931100

1094-
Model.prototype.$model = function $model(name) {
1095-
return this[modelDbSymbol].model(name);
1096-
};
1101+
Model.prototype.model = Model.prototype.$model;
10971102

10981103
/**
10991104
* Returns a document with `_id` only if at least one document exists in the database that matches

test/document.test.js

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12521,6 +12521,14 @@ describe('document', function() {
1252112521
assert.strictEqual(attachmentSchemaPreValidateCalls, 1);
1252212522
});
1252312523

12524+
it('returns constructor if using $model() with no args (gh-13878)', async function() {
12525+
const testSchema = new Schema({ name: String });
12526+
const Test = db.model('Test', testSchema);
12527+
12528+
const doc = new Test();
12529+
assert.strictEqual(doc.$model(), Test);
12530+
});
12531+
1252412532
it('avoids creating separate subpaths entry for every element in array (gh-13874)', async function() {
1252512533
const tradeSchema = new mongoose.Schema({ tradeId: Number, content: String });
1252612534

test/types/document.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -294,6 +294,17 @@ function gh12290() {
294294
user.isDirectModified('name');
295295
}
296296

297+
function gh13878() {
298+
const schema = new Schema({
299+
name: String,
300+
age: Number
301+
});
302+
const User = model('User', schema);
303+
const user = new User({ name: 'John', age: 30 });
304+
expectType<typeof User>(user.$model());
305+
expectType<typeof User>(user.model());
306+
}
307+
297308
function gh13094() {
298309
type UserDocumentNever = HydratedDocument<{ name: string }, Record<string, never>>;
299310

types/document.d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ declare module 'mongoose' {
7575

7676
/** Returns the model with the given name on this document's associated connection. */
7777
$model<ModelType = Model<unknown>>(name: string): ModelType;
78+
$model<ModelType = Model<DocType>>(): ModelType;
7879

7980
/**
8081
* A string containing the current operation that Mongoose is executing
@@ -191,6 +192,10 @@ declare module 'mongoose' {
191192
markModified<T extends keyof DocType>(path: T, scope?: any): void;
192193
markModified(path: string, scope?: any): void;
193194

195+
/** Returns the model with the given name on this document's associated connection. */
196+
model<ModelType = Model<unknown>>(name: string): ModelType;
197+
model<ModelType = Model<DocType>>(): ModelType;
198+
194199
/** Returns the list of paths that have been modified. */
195200
modifiedPaths(options?: { includeChildren?: boolean }): Array<string>;
196201

0 commit comments

Comments
 (0)