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

TypeScript QueryHelpers return any instead of model type #12342

Closed
2 tasks done
florianwalther-private opened this issue Aug 28, 2022 · 7 comments
Closed
2 tasks done
Labels
typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@florianwalther-private
Copy link

florianwalther-private commented Aug 28, 2022

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

6.5.3

Node.js version

16.3.2

MongoDB server version

5.0.11

Description

I implemented a query helper function following the tutorial documentation in the documentation.

As soon as I add this method, the return value of that query turns into any. It should return the proper model type instead.

Steps to Reproduce

Implement a query helper as outlined in the documentation: https://mongoosejs.com/docs/typescript/query-helpers.html

Expected Behavior

The return type after calling the query helper function should be the appropriate model type.

@IslandRhythms IslandRhythms added the typescript Types or Types-test related issue / Pull Request label Aug 29, 2022
@hasezoey
Copy link
Collaborator

i think the mentioned documentation is at least slightly out-of-date, because a proper type for query-helpers should be QueryWithHelpers instead of just Query?

@florianwalther-private
Copy link
Author

florianwalther-private commented Aug 29, 2022

I'm not sure what the correct return type is because I find it a bit confusing, but it should certainly not be any. After calling exec()/await, I want the model back like it does without the query helper chained to it.

@hasezoey
Copy link
Collaborator

hasezoey commented Aug 29, 2022

re #12347 (comment)

but the referenced (my) issue is not about the documentation

from what i can tell, this issue is about the documentation because "you followed the documentation, but its not working" and after having taken a look at the documentation and the current code in mongoose's actual types, i came to the conclusion that the documentation is probably outdated


reason for the documentation being outdated:
since the documentation has been written QueryWithHelpers has been added, which should make the types easier & cleaner, see

type QueryWithHelpers<ResultType, DocType, THelpers = {}, RawDocType = DocType> = Query<ResultType, DocType, THelpers, RawDocType> & THelpers;

by taking care of the Query<...> & Type

also the documentation lists the first parameter as a static any to Query<any, ...>, which is the result type, and so ending up in the wrong type

TL;DR: change your type to QueryWithHelpers for less code, and also change the first parameter from any to the actual return type


currently the documentation is basically guiding to be like (like in issue #12347)

): QueryWithHelpers<any, ResultDoc, TQueryHelpers, T>;

here it should actually be ResultDoc or {} and definitely not any, see

class Query<ResultType, DocType, THelpers = {}, RawDocType = DocType> implements SessionOperation {

mongoose/types/query.d.ts

Lines 182 to 184 in 0af4cb8

/** Executes the query */
exec(callback: Callback<ResultType>): void;
exec(): Promise<ResultType>;

TL;DR: if you are following the documentation, then you will be guaranteed to get any as a result after doing query.exec() (or query.then or implicitly like await query)

@florianwalther-private
Copy link
Author

florianwalther-private commented Aug 30, 2022

@hasezoey

Thank you for the explanation. I didn't know that only the docs were wrong.

But I'm unsure what to pass instead of any. If I only pass the interface type I use for my model, it doesn't work. Instead, I copy pasted the return type I get from normal queries, which works, but is very long and ugly:

(mongoose.Document<unknown, any, User> & User & Required<{
    _id: mongoose.Types.ObjectId;
}>) | null

Can you give me any tips here?

Also, if I understand it correctly, QueryWithHelpers lets me remove the TQueryHelpers type argument. Is there any other difference? I noticed that my code works the same with and without this argument even if I use the normal Query type.

@hasezoey
Copy link
Collaborator

Also, if I understand it correctly, QueryWithHelpers lets me remove the TQueryHelpers type argument. Is there any other difference? I noticed that my code works the same with and without this argument even if I use the normal Query type.

i basically suggested this because mongoose uses that internally over just Query, but i dont see other differences

Instead, I copy pasted the return type I get from normal queries, which works, but is very long and ugly:

the expected return-type (if the query returns a single) should be a document (or document array), which should be done with HydratedDocument<YourInterfaceType>, also if you have this once you can re-use that argument for both the first and second generic

like (updated documentation):

// note the "T" generic is just to store the same result for both the first and second generic for "QueryWithHelpers"
type ProjectModelQuery<T = HydratedDocument<Project>> = QueryWithHelpers<T | null, T, ProjectQueryHelpers>;
// or
type ProjectModelQuery = QueryWithHelpers<HydratedDocument<Project> | null, HydratedDocument<Project>, ProjectQueryHelpers>;

@florianwalther-private
Copy link
Author

@hasezoey Thank you so much! I think I tried HydratedDocument earlier but it didn't work because I didn't add the | null. Now it works!

@vkarpov15 vkarpov15 added this to the 6.6.4 milestone Sep 24, 2022
vkarpov15 added a commit that referenced this issue Oct 3, 2022
TypeScript query helpers quick fix and docs improvements
@vkarpov15
Copy link
Collaborator

Fixed by #12507

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
typescript Types or Types-test related issue / Pull Request
Projects
None yet
Development

No branches or pull requests

4 participants