diff --git a/mongoose/README.md b/mongoose/README.md
index 4a581dcfdb..03b483ecd1 100644
--- a/mongoose/README.md
+++ b/mongoose/README.md
@@ -1 +1,191 @@
-# TESTING
\ No newline at end of file
+## MongooseJS Typescript Docs
+Below are some examples of how to use these Definitions.
+Scenarios where the Typescript code is identical to plain Javascript code are omitted.
+
+#### Mongoose Methods, Properties, Constructors
+You can call methods from the mongoose instance using:
+```
+import * as mongoose from 'mongoose';
+var MyModel = mongoose.model(...);
+var MySchema: mongoose.Schema = new mongoose.Schema(...);
+```
+
+Alternatively, you can import individual names and call them:
+```
+import {model, Schema} from 'mongoose';
+var MyModel = model(...);
+var MySchema: Schema = new Schema(...):
+```
+
+
+#### Creating and Saving Documents
+```
+import {Document, model, Model, Schema} from 'mongoose';
+
+var UserSchema: Schema = new Schema({
+ username: {
+ type: String,
+ required: true,
+ unique: true
+ },
+ age: Number,
+ friends: [String],
+ data: [Schema.Types.Mixed]
+});
+
+interface IUser extends Document {
+ username: string;
+ age: number;
+ friends: string[];
+ data: any[];
+}
+
+var UserModel: Model = mongoose.model('User', UserSchema);
+
+var user = new UserModel({name: 'Jane'});
+user.username; // IUser properties are available
+user.save(); // mongoose Document methods are available
+
+UserModel.findOne({}, (err: any, user: IUser) => {
+ user.username; // IUser properties are available
+ user.save(); // mongoose Document methods are available
+});
+```
+
+#### Instance Methods and Virtual Properties
+```
+import {Document, model, Model, Schema} from 'mongoose';
+
+var UserSchema: Schema = new Schema({
+ name: String
+});
+
+UserSchema.methods.method1 = function () { return '' };
+UserSchema.virtual('nameInCaps').get(function () {
+ return this.name.toUpperCase();
+});
+UserSchema.virtual('nameInCaps').set(function (caps) {
+ this.name = caps.toLowerCase();
+});
+
+interface IUser extends Document {
+ name: string;
+ nameInCaps: string;
+ method1: () => string;
+}
+
+var UserModel: Model = model('User', UserSchema);
+var user = new UserModel({name: 'Billy'});
+
+user.method1(); // IUser methods are available
+user.nameInCaps; // virtual properties can be used
+
+UserModel.findOne({}, (err: any, user: IUser) => {
+ user.method1(); // IUser methods are available
+ user.nameInCaps; // virtual properties can be used
+});
+```
+
+#### Static Methods
+```
+import {Document, model, Model, Schema} from 'mongoose';
+
+var UserSchema = new Schema({});
+UserSchema.statics.static1 = function () { return '' };
+
+interface IUserDocument extends Document {...}
+interface IUserModel extends Model {
+ static1: () => string;
+}
+
+var UserModel: IUserModel = model('User', UserSchema);
+UserModel.static1(); // static methods are available
+```
+
+#### Plugins
+To write definitions for plugins, extend the mongoose module and create a simple plugin module:
+```
+// plugin.d.ts
+declare module 'mongoose' {
+ export interface PassportLocalDocument {...}
+ export interface PassportLocalSchema extends Schema {...}
+ export interface PassportLocalModel extends Model {...}
+ ...
+}
+
+declare module 'passport-local-mongoose' {
+ import mongoose = require('mongoose');
+ var _: (schema: mongoose.Schema, options?: Object) => void;
+ export = _;
+}
+
+// user.ts
+import {
+ model,
+ PassportLocalDocument,
+ PassportLocalSchema,
+ PassportLocalModel
+ Schema
+} from 'mongoose';
+import * as passportLocalMongoose from 'passport-local-mongoose';
+
+var UserSchema: PassportLocalSchema = new Schema({});
+UserSchema.plugin(passportLocalMongoose, options);
+
+interface IUser extends PassportLocalDocument {...}
+interface IUserModel extends PassportLocalModel {...}
+
+var UserModel: IUserModel = model('User', UserSchema);
+```
+Full example for [Passport Local Mongoose](https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/passport-local-mongoose/passport-local-mongoose.d.ts)
+
+#### Promises
+These definitions use global.Promise by default. If you would like to use mongoose's own mpromise
+definition (which is deprecated), you can install definitions for [mongoose-promise](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/mongoose-promise).
+
+If you'd like to use something other than global.Promise, you'll need to create a simple .d.ts file:
+```
+// promise-bluebird.d.ts
+import * as Bluebird from 'bluebird';
+
+declare module 'mongoose' {
+ type Promise = Bluebird;
+}
+
+// promise-q.d.ts
+import * as Q from 'q';
+
+declare module 'mongoose' {
+ type Promise = Q.Promise;
+}
+
+// another-promise.d.ts
+...
+```
+To use it, you will need to `/// ` in one of your source code files,
+or include the `.d.ts` file in your compile.
+
+To assign the new promise library in your code, you will need to use one of the following options (since
+Typescript does not allow assigning properties of imported modules):
+
+* `(mongoose).Promise = YOUR_PROMISE;`
+* `require('mongoose').Promise = YOUR_PROMISE;`
+* `import mongoose = require('mongoose'); ... mongoose.Promise = YOUR_PROMISE;`
+
+#### FAQ
+Q: Why are there 2 interfaces for Documents called Document and MongooseDocument?
+A: People have been using this for a long time:
+```
+interface IUser extends mongoose.Document {
+ ...
+}
+```
+When it should really be this:
+```
+interface IUser extends mongoose.model {
+ ...
+}
+```
+For backwards compatibility Document is an interface for [mongoose.model](https://github.com/Automattic/mongoose/blob/master/lib/model.js#L3162)
+And MongooseDocument is an interface for [mongoose.Document](https://github.com/Automattic/mongoose/blob/master/lib/model.js#L3162)
+At some point in the future this may get fixed, which would require fixing your code.
\ No newline at end of file
diff --git a/mongoose/mongoose-tests.ts b/mongoose/mongoose-tests.ts
index d846023143..51959b9e41 100644
--- a/mongoose/mongoose-tests.ts
+++ b/mongoose/mongoose-tests.ts
@@ -1379,4 +1379,10 @@ Final.findOne(function (err: any, doc: MyDocument) {
doc.save();
doc.remove();
doc.model('');
-});
\ No newline at end of file
+});
+export var Final2: MyModel = mongoose.model('Final2', mySchema);
+Final2.staticMethod();
+Final2.staticProp;
+var final2 = new Final2();
+final2.prop;
+final2.method;
\ No newline at end of file
diff --git a/mongoose/mongoose.d.ts b/mongoose/mongoose.d.ts
index b28a222778..81247104ef 100644
--- a/mongoose/mongoose.d.ts
+++ b/mongoose/mongoose.d.ts
@@ -152,6 +152,12 @@ declare module "mongoose" {
*/
export function model(name: string, schema?: Schema, collection?: string,
skipInit?: boolean): Model;
+ export function model>(
+ name: string,
+ schema?: Schema,
+ collection?: string,
+ skipInit?: boolean
+ ): U;
/**
* Returns an array of model names created on this instance of Mongoose.
@@ -311,6 +317,11 @@ declare module "mongoose" {
* @returns The compiled model
*/
model(name: string, schema?: Schema, collection?: string): Model;
+ model>(
+ name: string,
+ schema?: Schema,
+ collection?: string
+ ): U;
/** Returns an array of model names created on this connection. */
modelNames(): string[];
@@ -704,7 +715,7 @@ declare module "mongoose" {
* section document.js
* http://mongoosejs.com/docs/api.html#document-js
*/
- class MongooseDocument {
+ interface MongooseDocument {
/** Checks if a path is set to its default. */
$isDefault(path?: string): boolean;
@@ -2074,7 +2085,7 @@ declare module "mongoose" {
findById(id: Object | string | number, projection: Object, options: Object,
callback?: (err: any, res: T) => void): DocumentQuery;
- model(name: string): Model;
+ model(name: string): Model;
/**
* Creates a Query and specifies a $where condition.
diff --git a/passport-local-mongoose/passport-local-mongoose-tests.ts b/passport-local-mongoose/passport-local-mongoose-tests.ts
index 993d5b05da..c7d4ffc381 100644
--- a/passport-local-mongoose/passport-local-mongoose-tests.ts
+++ b/passport-local-mongoose/passport-local-mongoose-tests.ts
@@ -34,7 +34,7 @@ interface User extends PassportLocalDocument {
last: Date;
}
-const UserSchema: PassportLocalSchema = new Schema({
+const UserSchema: PassportLocalSchema = new Schema({
username: String,
hash: String,
salt: String,