title: Header files for Mongoose' 'plugin' method (extending via .methods and .statics)
body: <p>I'm trying to create Typescript header files for a <a href="https://github.com/saintedlama/passport-local-mongoose" rel="nofollow">script</a> that extends my Mongoose-model by using the .plugin method. Current signature from <a href="https://github.com/borisyankov/DefinitelyTyped/blob/master/mongoose/mongoose.d.ts#L111" rel="nofollow">Mongoose header-files</a>:</p>
  
  <pre><code>export class Schema {
     // ...
     plugin(plugin: (schema: Schema, options?: Object) =&gt; void, 
                     options?: Object): Schema;
     // ...
  }
  </code></pre>
  
  <p>Some actual code from <a href="https://github.com/Automattic/mongoose/blob/master/lib/schema.js#L749" rel="nofollow">Mongoose-lib</a>:</p>
  
  <pre><code>/**
   * 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;
  };
  </code></pre>
  
  <p>Then my own model, extending the <a href="https://github.com/saintedlama/passport-local-mongoose" rel="nofollow">plugin</a>;</p>
  
  <pre><code>import passportLocalMongoose = require('passport-local-mongoose')
  // ...
  var userSchema = new mongoose.Schema({
      email: String,
      password: String,
  });
  // ...
  userSchema.plugin(passportLocalMongoose, {
      usernameField: "email",
      usernameLowerCase: true
  });
  </code></pre>
  
  <p>Snippet from <a href="https://github.com/saintedlama/passport-local-mongoose" rel="nofollow">passport-local-mongoose</a> source:</p>
  
  <pre><code>module.exports = function(schema, options) {
     // ...   
     schema.methods.setPassword = function (password, cb) {
        // ...
     }
  
     schema.statics.authenticate = function() {
        // ...
     }
     // ...
  }
  </code></pre>
  
  <p>Problem occurs in my main app.js</p>
  
  <pre><code>   // ...
  
     userSchema.authenticate()                // &lt;&lt;&lt; Typescript error, undefined
  
     //   OR
  
     userSchemaInstance.setPassword(pass, cb) // &lt;&lt;&lt; Typescript error, undefined
  </code></pre>
  
  <p>The problem is that .authenticate etc. were dynamically added through <a href="https://github.com/saintedlama/passport-local-mongoose/blob/master/lib/passport-local-mongoose.js#L83" rel="nofollow">.methods</a> and <a href="https://github.com/saintedlama/passport-local-mongoose/blob/master/lib/passport-local-mongoose.js#L177" rel="nofollow">.statics</a> ...  </p>
  
  <p>I can't find a way to model this in the typescript header files. </p>
  
  <p>I tried generics and stuff, but I can't (dynamic) apply the provide plugin-methods back to the original model. I also tried <code>plugin</code> returning generic <code>T extends S &amp; P</code> (where S extends Schema from first argument and P = plugin itself).   No luck :-(</p>
  
  <p>Any suggestions or examples how to solve this?</p>