Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(document): allow calling $model() with no args for TypeScript #13963

Merged
merged 2 commits into from
Oct 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
33 changes: 19 additions & 14 deletions lib/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -1060,40 +1060,45 @@ Model.prototype.$__deleteOne = function $__deleteOne(options, cb) {
};

/**
* Returns another Model instance.
* Returns the model instance used to create this document if no `name` specified.
* If `name` specified, returns the model with the given `name`.
*
* #### Example:
*
* const doc = new Tank;
* await doc.model('User').findById(id);
* const doc = new Tank({});
* doc.$model() === Tank; // true
* await doc.$model('User').findById(id);
*
* @param {String} name model name
* @method model
* @param {String} [name] model name
* @method $model
* @api public
* @return {Model}
*/

Model.prototype.model = function model(name) {
Model.prototype.$model = function $model(name) {
if (arguments.length === 0) {
return this.constructor;
}
return this[modelDbSymbol].model(name);
};

/**
* Returns another Model instance.
* Returns the model instance used to create this document if no `name` specified.
* If `name` specified, returns the model with the given `name`.
*
* #### Example:
*
* const doc = new Tank;
* await doc.model('User').findById(id);
* const doc = new Tank({});
* doc.$model() === Tank; // true
* await doc.$model('User').findById(id);
*
* @param {String} name model name
* @method $model
* @param {String} [name] model name
* @method model
* @api public
* @return {Model}
*/

Model.prototype.$model = function $model(name) {
return this[modelDbSymbol].model(name);
};
Model.prototype.model = Model.prototype.$model;

/**
* Returns a document with `_id` only if at least one document exists in the database that matches
Expand Down
8 changes: 8 additions & 0 deletions test/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -12521,6 +12521,14 @@ describe('document', function() {
assert.strictEqual(attachmentSchemaPreValidateCalls, 1);
});

it('returns constructor if using $model() with no args (gh-13878)', async function() {
const testSchema = new Schema({ name: String });
const Test = db.model('Test', testSchema);

const doc = new Test();
assert.strictEqual(doc.$model(), Test);
});

it('avoids creating separate subpaths entry for every element in array (gh-13874)', async function() {
const tradeSchema = new mongoose.Schema({ tradeId: Number, content: String });

Expand Down
11 changes: 11 additions & 0 deletions test/types/document.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,17 @@ function gh12290() {
user.isDirectModified('name');
}

function gh13878() {
const schema = new Schema({
name: String,
age: Number
});
const User = model('User', schema);
const user = new User({ name: 'John', age: 30 });
expectType<typeof User>(user.$model());
expectType<typeof User>(user.model());
}

function gh13094() {
type UserDocumentNever = HydratedDocument<{ name: string }, Record<string, never>>;

Expand Down
5 changes: 5 additions & 0 deletions types/document.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ declare module 'mongoose' {

/** Returns the model with the given name on this document's associated connection. */
$model<ModelType = Model<unknown>>(name: string): ModelType;
$model<ModelType = Model<DocType>>(): ModelType;
hasezoey marked this conversation as resolved.
Show resolved Hide resolved

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

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

/** Returns the list of paths that have been modified. */
modifiedPaths(options?: { includeChildren?: boolean }): Array<string>;

Expand Down