My task is to develop Typescript header files for a script that enhances my Mongoose model using the .plugin method. The current signature in the Mongoose header files looks like this:
export class Schema {
// ...
plugin(plugin: (schema: Schema, options?: Object) => void,
options?: Object): Schema;
// ...
}
Here is a snippet of code from the Mongoose library:
/**
* Registers a plugin for this schema.
*
* @param {Function} plugin callback
* @param {Object} [opts]
* @see plugins
* @api public
*/
Schema.prototype.plugin = function (fn, opts) {
fn(this, opts);
return this;
};
Next, I created my own model by extending the plugin:
import passportLocalMongoose = require('passport-local-mongoose')
// ...
var userSchema = new mongoose.Schema({
email: String,
password: String,
});
// ...
userSchema.plugin(passportLocalMongoose, {
usernameField: "email",
usernameLowerCase: true
});
This is an excerpt from the source code of passport-local-mongoose:
module.exports = function(schema, options) {
// ...
schema.methods.setPassword = function (password, cb) {
// ...
}
schema.statics.authenticate = function() {
// ...
}
// ...
}
Now, the problem arises in my main app.js file:
// ...
userSchema.authenticate() // <<< Typescript error, undefined
// OR
userSchemaInstance.setPassword(pass, cb) // <<< Typescript error, undefined
The issue stems from the fact that .authenticate and others were dynamically added through .methods and .statics. I am struggling to represent this in the typescript header files.
I have experimented with generics and other approaches, but I cannot dynamically apply the provided plugin-methods back to the original model. I even tried plugin
returning generic T extends S & P
(where S extends Schema from the first argument and P represents the plugin itself). Unfortunately, I have had no success so far.
Does anyone have suggestions or examples on how to tackle this challenge?