Mongoose: Provide a definitely typed file (.d.ts) for TypeScript

Created on 6 Mar 2016  路  28Comments  路  Source: Automattic/mongoose

There is only a .d.ts file for mongoose 3.x at https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/mongoose/mongoose.d.ts.
Therefore, you get tons of syntax errors when using this outdated file together with mongoose 4.4.6.

Most helpful comment

Thank you @simonxca . (<any>mongoose).Promise = Promise solved the compilation error.

All 28 comments

You're more than welcome to contribute one. I have zero experience with TypeScript.

I'd consider this pretty importing seeing as TypeScript is on the rise. I have no experience with all the quirks of writing definition files, but they should be done by someone who knows the mongoose API really well.

@juergenzimmermann @DamonGant I've updated the Typescript definitions, please try them here:
https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/mongoose/mongoose.d.ts

@simonxca I'm having TypeScript 2.0 beta and use its "@types" mechanism. Does it mean that your mongoose.d.ts can only installed via typings?

@simonxca OK, I installed typings and mongoose.d.ts from Definitely Typed (via typings). Now I'm getting tons of Errors like this one:
typings\globals\mongoose\index.d.ts(185,34): error TS2304: Cannot find name 'MongoosePromise'.
Can you give me a hint, please?

@juergenzimmermann It's installed via typings for now using typings install dt~mongoose --global

From what I hear, they are planning to move everything to @types/mongoose in the future, but they haven't quite worked out the details. @types/mongoose is in another format, and for now it looks like someone from DefinitelyTyped manually converts the definitions so they're probably outdated.

@juergenzimmermann Don't think typings install dt~mongoose --global installs dependencies.

1) Make sure you have mongodb and node definitions installed.
typings install dt~node dt~mongodb --global

2) Mongoose lets you use your own promise library in your code. mongoose.Promise = your_promise

If you're using the default mpromise, you should:
typings install dt~mongoose-promise --global

If you're using native ES6 promises, add a line in your main .d.ts file:
type MongoosePromise<T> = Promise<T>

If you're using another library, example q, you should:
typings install dt~q --global
Then add a line in your main .d.ts file:
type MongoosePromise<T> = Q.Promise<T>

If you get more errors please copy some of them on here and I'll take a look.

@simonxca got it, thank you. Now only 2 errors are remaining.

src\buchverwaltung\service\buecher.service.ts(120,21): error TS2339: Property 'save' does not exist on type 'Document'.

This is my source code:

const buch: Document = ...;
...
buch.save();

How do I have to import the class _Model<T> which has the property save() and extends Document?

The other compilation error is

typings\globals\mongoose\index.d.ts(989,13): error TS2415: Class 'Array<T>' incorrectly extends base class 'any[]'.
  Types of property 'sort' are incompatible.
    Type '(compare?: Function) => T[]' is not assignable to type '(compareFn?: (a: any, b: any) => number) => this'.
      Type 'T[]' is not assignable to type 'this'.

@juergenzimmermann For the first error, there was a document.save() in the previous definitions, but there's actually no .save() method on Document http://mongoosejs.com/docs/api.html#document-js

You should use const buch: mongoose.model<T> for what is commonly known as "documents"
The types should look like this:

var Model: mongoose.Model<T> = mongoose.model(...);
var model: mongoose.model<T> = new Model();

Let me know if that makes sense.

Actually these types are not final yet. I could change it to be like this:

var Model: mongoose.ModelConstructor<T> = mongoose.model(...);
var model: mongoose.Model<T> = new Model();

Do you think that would make more sense?

For the second error, that is an error with the definitions. Good catch! I'll add a fix for it. Try commenting out the sort() method in the definitions see if that works.

@simonxca Thank you very much! Both issues (i.e. mongoose.Model and sort()) are gone.

I'd prefer the current variant, i.e. Model over ModelConstructor.

@juergenzimmermann Great! Thanks for your feedback.

@simonxca a new issue came up, since Mongoose deprecated the mpromise library. Therefore; I'm doing the following according to https://github.com/Automattic/mongoose/issues/4291##issuecomment-230312093:

import * as mongoose from 'mongoose';
...
mongoose.Promise = global.Promise;

But now I'm getting this error message when compiling with TypeScript:

src\shared\config\db.ts(40,1): error TS2450: Left-hand side of assignment expression cannot be a constant or a read-only property.

@juergenzimmermann Hmm, I've never seen that before. I also can't reproduce it with the latest version of Typescript.

  1. Can you show me what your tsconfig.json looks like?
  2. Maybe try mongoose.Promise = Promise they are the same object except global.Promise links to node's definitions node.d.ts and Promise links to Typescript's lib.d.ts
  3. If nothing else you can do (<any>mongoose).Promise = Promise. It's a little ugly, but it doesn't affect behaviour.

@juergenzimmermann Or try require('mongoose').Promise = Promise
If that throws an error, then the problem is something else since this is just plain javascript.

Thank you @simonxca . (<any>mongoose).Promise = Promise solved the compilation error.

or you can use mongoose.Promise = <any>Promise instead

@simonxca I'm still seeing a similar error concerning the Array<T>.sort method:

970       class Array<T> extends global.Array {
                ~~~~~

typings/globals/mongoose/index.d.ts(970,13): error TS2415: Class 'Array<T>' incorrectly extends base class 'any[]'.
  Types of property 'sort' are incompatible.
    Type '(compareFn?: ((a: T, b: T) => number) | undefined) => any[]' is not assignable to type '(compareFn?: ((a: any, b: any) => number) | undefined) => this'.
      Type 'any[]' is not assignable to type 'this'.

3:37:41 PM - Compilation complete. Watching for file changes.

I'm using Typescript 2.00, Typings 1.3.2 and the latest types' definition:

"mongoose": "registry:dt/mongoose#4.5.4+20160804041818",

@serhiisol @derenio Looks like Typescript's Array.sort() signature has changed: https://github.com/Microsoft/TypeScript/blob/master/lib/lib.es6.d.ts#L1155 I have Typescript 1.5.3, my lib.d.ts still has: sort(compareFn?: (a: T, b: T) => number): T[]; Hence the error. I'll comment out the sort method since global.Array provides it anyway whatever version of lib.d.ts people have. You can do the same for now.

@simonxca Running into the same build error with sort() as well. Other than commenting it out, what would be an ideal longer term or permanent solution?

@douglasg14b The DT definitions have it commented out so it should work out of the box now. The inherited global.Array would provide the sort() method so I don't think it should cause too many issues.

I am getting an error on the create where Promise returns just an object rather than an array of Objects. https://github.com/DefinitelyTyped/DefinitelyTyped/blob/master/mongoose/index.d.ts#L2319
should we add a line below? This works on mongoose 4.7:

create(doc: Object, fn?: (err: any, res: T) => void): Promise<T>;

@fpereira1 yea, something's weird about the create() definition. Can you show me some sample code that breaks to test with?

@simonxca I am basically trying something like this:

const post = await postsFixtures.create({ content : 'text content' });
t.is(posts[0].content, post.content);

without the line above added to my version of the mongoose typings in the node_modules/@types the compiler error that I am getting is:

error TS2339: Property 'content' does not exist on type 'any[]'.

@fpereira1 hmm okay I added your line here. Could you give the fix a try? https://raw.githubusercontent.com/simonxca/DefinitelyTyped/patch-mongoose/mongoose/index.d.ts

i can't find the definition for MongooseDocumentArray!

@simonxca found, thanks!

Gonna close this. DefinitelyTyped has support for this and TS support is outside the scope of core mongoose.

Was this page helpful?
0 / 5 - 0 ratings