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

types(model): aligned watch() type for mongodb 4.6.0 #13208

Merged
merged 1 commit into from Apr 5, 2023

Conversation

lpizzinidev
Copy link
Contributor

@lpizzinidev lpizzinidev commented Mar 24, 2023

Summary
You can now specify the custom type for the top-level document returned in a change event.
This aligns with the changes introduced in MongoDB 4.6.0.

Example

TestModel.watch<ITest, ChangeStreamInsertDocument<ITest>>([]).on('change', (change) => {
    console.log(change.fullDocument); // TS won't complain
});

Closes #13206

@@ -382,7 +382,7 @@ declare module 'mongoose' {
validate(optional: any, pathsToValidate: PathsToValidate): Promise<void>;

/** Watches the underlying collection for changes using [MongoDB change streams](https://www.mongodb.com/docs/manual/changeStreams/). */
watch<ResultType extends mongodb.Document = any>(pipeline?: Array<Record<string, unknown>>, options?: mongodb.ChangeStreamOptions & { hydrate?: boolean }): mongodb.ChangeStream<ResultType>;
watch<ResultType extends mongodb.Document = any, ChangeType extends mongodb.ChangeStreamDocument = any>(pipeline?: Array<Record<string, unknown>>, options?: mongodb.ChangeStreamOptions & { hydrate?: boolean }): mongodb.ChangeStream<ResultType, ChangeType>;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't it be better if we added a separate overload for watch() with options: mongodb.ChangeStreamOptions & { fullDocument: 'updateLookup', hydrate?: boolean } that added fullDocument to the result? It looks like this approach relies on the user to specify the correct type

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From my understanding of the changelog, the added feature is that the dev can now specify ChangeType, the type of the change document.
It is not related to the options parameter (I wrote an unclear example above, now edited).

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I took a closer look and @lpizzinidev is correct, the expected behavior here is that the user can overwrite the valid change types. fullDocument: 'updateLookup' doesn't always ensure that there will be a fullDocument property, for example deletes. Below is an example script I used to verify:

import mongoose from 'mongoose';

mongoose.set('debug', true);

run().catch(err => console.error(err));

async function run() {
  await mongoose.connect('mongodb://localhost:27017,localhost:27018,localhost:27019/mongoose_test');
  await mongoose.connection.dropDatabase();

  const TestModel = mongoose.model('Test', new mongoose.Schema({ name: String }));
  await TestModel.createCollection();

  await TestModel.
    watch<{name:string}>([], { fullDocument: 'updateLookup' }).
    on('change', change => console.log(change));
  await TestModel.create({ name: 'foo' });
  await TestModel.updateOne({ name: 'foo' }, { name: 'bar' });
  await TestModel.deleteOne({ name: 'bar' });
  console.log('Wrote document');
}

@vkarpov15 vkarpov15 merged commit 90ea063 into Automattic:master Apr 5, 2023
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[TypeScript] watch().on doesn't have correct type on callback, so can't access fullDocument
2 participants