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

Type definition for Query.updateOne is wrong - options such as new are not supported by Mongo #14204

Closed
2 tasks done
Woodz opened this issue Dec 29, 2023 · 3 comments · Fixed by #14228
Closed
2 tasks done
Labels
typescript Types or Types-test related issue / Pull Request
Milestone

Comments

@Woodz
Copy link

Woodz commented Dec 29, 2023

Prerequisites

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

Mongoose version

8.1

Node.js version

20.x

MongoDB server version

7.0

Typescript version (if applicable)

5.x

Description

The type definition of Query.updateOne is incorrect - it contains extra fields that are not used by Mongo, which can cause confusion for users. Specifically, updateOne in Mongo only supports (https://www.mongodb.com/docs/manual/reference/method/db.collection.updateOne/#syntax):

updateOne(
      filter?: FilterQuery<RawDocType>,
      update?: UpdateQuery<RawDocType> | UpdateWithAggregationPipeline,
      options?: QueryOptions<DocType> | null
    ): QueryWithHelpers<UpdateWriteOpResult, DocType, THelpers, RawDocType, 'updateOne'>;

where QueryOptions has many extra fields, including (https://github.com/Automattic/mongoose/blob/8.1/types/query.d.ts#L98):

  • new
  • projection
  • batchSize
  • returnOriginal
  • returnDocument,
    etc.

These extra fields cause confusion because they are not used by Mongo and therefore should be removed to provide accurate typing

Steps to Reproduce

Type definitions do not need reproduction steps

Expected Behavior

No response

@vkarpov15
Copy link
Collaborator

First, as a general rule, "Type definitions do not need reproduction steps" is incorrect; type definitions absolutely need reproduction steps most of the time. This issue is to some extent an exception, so fine for now.

That being said, Mongoose's type definitions are correct in this case because of chaining. For example, the following is perfectly valid: Model.updateOne({ name: 'foo' }, { name: 'bar' }, { returnDocument: 'after' }).findOneAndUpdate(). However, that doesn't line up well with how these functions are commonly used, so we put in a PR to improve that.

@vkarpov15 vkarpov15 added the typescript Types or Types-test related issue / Pull Request label Jan 2, 2024
@vkarpov15 vkarpov15 added this to the 8.0.4 milestone Jan 2, 2024
donoftime2018 added a commit to donoftime2018/mongoose that referenced this issue Jan 2, 2024
removed unnecessary parameters from QueryOptions interface issue Automattic#14204
vkarpov15 added a commit that referenced this issue Jan 3, 2024
types(model+query): use stricter typings for updateX(), replaceOne(),deleteX() Model functions
@Woodz
Copy link
Author

Woodz commented Feb 1, 2024

Thank you for promptly resolving this issue - I really appreciate it!

First, as a general rule, "Type definitions do not need reproduction steps" is incorrect; type definitions absolutely need reproduction steps most of the time. This issue is to some extent an exception, so fine for now.

I think I understand what you mean - if a developer is seeing something wrong with the typing when they are using the library, you would want them to tell you how they are using the API to be able to reproduce to identify the root cause. Whereas an issue like this one that has already identified the root cause doesn't have reproduction steps. So I should have phrased it - "no reproduction steps needed"

That being said, Mongoose's type definitions are correct in this case because of chaining. For example, the following is perfectly valid: Model.updateOne({ name: 'foo' }, { name: 'bar' }, { returnDocument: 'after' }).findOneAndUpdate(). However, that doesn't line up well with how these functions are commonly used, so we put in a PR to improve that.

Hmm, I'm not sure that fluent API approach is very safe - surely each separate call should be self-contained with only the result chaining forwards?
E.g.
Model.updateOne({ name: 'foo' }, { name: 'bar' }).findOneAndUpdate({ returnDocument: 'after' })

@vkarpov15
Copy link
Collaborator

The fluent API approach isn't very type safe, that's true. However, given that Model.updateOne({ name: 'foo' }, { name: 'bar' }, { returnDocument: 'after' }).findOneAndUpdate() is valid JavaScript that works as expected, I think it is reasonable to allow.

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
2 participants