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

Official TypeScript definitions #8108

Closed
vkarpov15 opened this issue Aug 28, 2019 · 29 comments
Closed

Official TypeScript definitions #8108

vkarpov15 opened this issue Aug 28, 2019 · 29 comments
Labels
discussion If you have any thoughts or comments on this issue, please share them! enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Milestone

Comments

@vkarpov15
Copy link
Collaborator

No description provided.

@vkarpov15 vkarpov15 added enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature discussion If you have any thoughts or comments on this issue, please share them! labels Aug 28, 2019
@vkarpov15 vkarpov15 added this to the Parking Lot milestone Aug 28, 2019
@kevinclarkadstech
Copy link

I am about to open an issue regarding the fairly poor TS support, especially compared to the official Mongo client. Way too much use of any and not using generics well enough makes querying give no compile time support, say if a property name changes.

@vkarpov15
Copy link
Collaborator Author

@kevinclarkadstech I'm sorry to hear about that. Can you provide some examples of code that's hard to write with TypeScript? Would be handy to have some concrete examples so we know where to start.

@taxilian
Copy link
Contributor

taxilian commented Sep 4, 2019

@vkarpov15 I would be very interested in helping with this and potentially taking point on maintaining this. I just finished a major refactor of the types currently in definitelytyped and have been trying to figure out how best to submit them. I am confident that @jloveridge will be interested in helping as we use mongoose with typescript at GradeCam and have for almost two years now.

If you're interested I'd like to discuss more directly with you sometime and see if we can get on the same page with what you'd like; there are a lot of things which could be improved by tying it together with mongoose itself because with some simple API changes (which could be optional) we could do a lot more with automatic type inference.

@kevinclarkadstech
Copy link

sure, say if I have a model:

interface Todo {
  done: boolean,
  text: string
}

type TodoDocument = Todo & Document;

const TodoModel: Model<TodoDocument> =...

when I say:

TodoModel.find({

I expect to get autocomplete/intellisense where conditions is a Partial which would give me type safety and autocomplete when saying:

{ _id: id }

or

{ done: false }

Because the TS definitions have any, there is no type safety or intellisense:

update(conditions: any, doc: any,
      callback?: (err: any, raw: any) => void): Query<any> & QueryHelpers;

@taxilian
Copy link
Contributor

taxilian commented Sep 4, 2019

@kevinclarkadstech I've got a pretty solid idea of how to fix that but haven't taken the time to do so yet even on my branch; my most recent additions (which I haven't tried yet to get merged to definitelytyped) will let you do a lean or .toObject and get back a Todo interface stripped of any functions your interface may have -- if you're interested in playing with it / helping me brainstorm on it shoot me an email rbateman@gradecam.com and I'll send you my local version and we can collaborate a bit while we wait for @vkarpov15 to decide how he wants to handle the official versions =]

@jloveridge
Copy link

@kevinclarkadstech one thing to consider when creating your search criteria, it isn't just as straightforward as saying {_id: id}. There are many other operations you can do such as: {_id: {$in: ids}}. I am not saying it is impossible but there will be a lot of complications in making search criteria "typesafe" without becoming overly restrictive.

@kevinclarkadstech
Copy link

rbateman@gradecam.com

Cool, I'll shoot you an email!

@kevinclarkadstech
Copy link

@kevinclarkadstech one thing to consider when creating your search criteria, it isn't just as straightforward as saying {_id: id}. There are many other operations you can do such as: {_id: {$in: ids}}. I am not saying it is impossible but there will be a lot of complications in making search criteria "typesafe" without becoming overly restrictive.

Yeah, I think the official Mongo Db Node client does something like a union type of Partial | any so you get some intellisense but if you are adding any of the more advanced queries you get no intellisense but TS also does not complain either. Theirs are still not ideal because you still have to refer to the docs a lot.

@kevinclarkadstech
Copy link

Since Mongoose is already a wrapper around the Mongo Db queries, why not have some helper functions that translate input into Mongo Db query? Say my collection was based on interface

  id: string;
  added: Date;
  addedBy: string;
  content: string;
  done: boolean;
}

Something like:

 new Query<Todo>().project(['id', 'content', 'done']).in({ 'addedBy': ['joe', 'fred'] }).eq({ done: false }).lt({ 'added': new Date() });

to get the id, content, done for users joe and fred where done is false and the added date is less than today.

I think that would make the ORM more useful than find(anything). Just my .02.

@kevinclarkadstech
Copy link

would be something like

class Query<Schema> {
  
  project(properties: keyof Schema[]): this {

  }

// Something like this, I can't remember how to write it
  in(propAndValue: { [keyof Schema: string]: typeof keyof Schema }): this {

  }

  lt( // same as above): this {

  }

}

@LucGranato
Copy link
Contributor

Hey guys!

Have you ever tried typegoose?

I'm starting a new project which implements TypeScript, but having to define both the Mongoose model and the TypeScript interface is very annoying and error-prone.

I'm giving a shot to typegoose and it seems to be an excellent work.
I think it would be nice to join our efforts to make typegoose the main solution for mongoose TypeScript , what do you think?

Someone has any experience with typegoose to share?

Thanks!

@alexbudure
Copy link

@LucGranato I've tried typegoose, but stopped using it when I found out it doesn't do what @kevinclarkadstech is talking about. Prisma is the only project I know that is doing type-safe database access. It would be awesome if mongoose is able to provide the same level of type-safety, but I believe that's only possible by auto generating types based on the schema.

@captaincaius
Copy link
Contributor

I've been chipping away at several approaches to this recently, and I've got the tricky part of deriving a typescript type from a schema configuration pojo working.

So far it works for numbers, strings, arrays, objects, and custom SchemaTypes. To make it a reality, though, it'll require a few compromises. So I wanted to ask if it'd be okay if:

  • Schema has an additional member that's similar to "obj" (currentConfigObject?), but it also tracks impure modifications to the schema through methods like "add" (shouldn't be hard to write).
  • to support custom SchemaTypes, we make a sacrificial property on SchemaType that's illegal to use for any other purpose other than mapping a schema type to its typescript type (e.g. UrlSchemaType.typescriptType: string).

...and actually... that seems to be it!

@vkarpov15 would you be open to Schema having a separate "obj" twin that stays up to date with changes to the schema?

If so, I'll continue down this approach and wrap it up (and update Model, Schema, find*, create, etc so that documents come out with all their types attached).

@captaincaius
Copy link
Contributor

Actually, having a "obj" twin that's kept up-to-date will make #8207 not really needed either cause it can be a separate project.

@captaincaius
Copy link
Contributor

Decided to throw it on gist:

https://gist.github.com/captaincaius/815d6d33141cd2d28458c6edef583054

LMK whether I should keep going on it...

@taxilian
Copy link
Contributor

taxilian commented Oct 3, 2019

We have a different method that we've been using which for us works extremely well; it uses decorators to basically define a class which doesn't actually get used directly but seems to (it's a little confusing at first, is the main drawback; it's actually very simple to use).

It's published here: https://github.com/gradecam/mongoose-decorators-ts

There are a number of improvements that we've made which haven't made it into that yet; I'm using it both at GradeCam and on hamstudy.org, a side project of mine, and it's been extremely helpful.

@captaincaius
Copy link
Contributor

@taxilian interesting - it looks VERY similar to typegoose from the outside. I look forward to looking at the code when I have some time :).

Anyway what I'm suggesting would likely benefit mongoose-decorators-ts in addition to typegoose. For example, after you've got a model, newing up a document will have types on it. I'm not sure about mongoose-decorators-ts, but at least for typegoose it can offload some of the work that's kind of unclear where it should be maintained (i.e. mongoose maintains the relationship between mongoose schema definitions to types, and typegoose / mongoose-decorators-ts only worries about describing a mongoose schema definition using decorated classes).

@taxilian
Copy link
Contributor

taxilian commented Oct 3, 2019

@captaincaius I can definitely see why you might get that impression on first glance, but actually mongoose-decorators-ts actually defines the types as classes and then generates a schema from that which is actually what is used -- so the type you create with the class is actually the types that you are using; it therefore solves both problems in one definition.

@taxilian
Copy link
Contributor

taxilian commented Oct 3, 2019

That said, I do think there are a number of projects which could benefit from something like what you're doing; I've thought about it myself a few times; if I were to approach it I'd probably try to make js-schema (or whatever it is mongodb validation uses) work, but I haven't gotten far enough to validate the feasibility of that yet

@caub
Copy link
Contributor

caub commented Dec 7, 2019

What I miss the most (using vscode as code editor) is if a mongoose models use .methods or .statics methods, I can't go to definition, or find references. The only way is a code search

I'm using JS, and I'd like to just introduce some .d.ts or some comments to type those model methods. Without having to repeat myself/duplicate the schema props like in the comment in #8119

@taxilian
Copy link
Contributor

taxilian commented Dec 7, 2019

@caub that is the specific problem the mongoose’s decorators project I linked addresses

vkarpov15 added a commit that referenced this issue Nov 10, 2020
vkarpov15 added a commit that referenced this issue Nov 13, 2020
vkarpov15 added a commit that referenced this issue Nov 16, 2020
vkarpov15 added a commit that referenced this issue Nov 16, 2020
vkarpov15 added a commit that referenced this issue Nov 17, 2020
vkarpov15 added a commit that referenced this issue Nov 19, 2020
vkarpov15 added a commit that referenced this issue Nov 30, 2020
@ahmedbrandver
Copy link

ahmedbrandver commented Dec 10, 2020

Is mongoose support for typescript is released?

@AbdelrahmanHafez
Copy link
Collaborator

@ahmedbrandver Yes, it was released since v5.11.

@Automattic Automattic locked and limited conversation to collaborators Dec 10, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
discussion If you have any thoughts or comments on this issue, please share them! enhancement This issue is a user-facing general improvement that doesn't fix a bug or add a new feature
Projects
None yet
Development

No branches or pull requests