-
-
Notifications
You must be signed in to change notification settings - Fork 3.8k
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
Mongoose types incorrect for when rawResult: true is set within findOneAndUpdate middleware #13987
Comments
just as a note, the mongoose code example is wrong (you try to call schema function const UserSchema = new mongoose.Schema({
id: String,
username: Number,
});
UserSchema.post('findOneAndUpdate', function (doc, next) {
// TYPES indicate doc.id but actual passed is doc.value.id
doc.value.id = doc.value._id;
// TYPES indicate doc.save() but actual passed is doc.value.save()
doc.value.save();
next();
});
const UserModel = mongoose.model('User', UserSchema); |
import * as mongoose from 'mongoose';
const UserSchema = new mongoose.Schema({
id: String,
username: String,
});
UserSchema.post('findOneAndUpdate', function (doc) {
console.log('what is doc', doc);
// TYPES indicate doc.id but actual passed is doc.value.id
doc.value.id = doc.value._id.toString();
// TYPES indicate doc.save() but actual passed is doc.value.save()
doc.value.save();
});
const UserModel = mongoose.model('User', UserSchema);
async function main() {
await mongoose.connect(`mongodb://localhost:27017/`);
await mongoose.connection.dropDatabase();
const doc = new UserModel({ username: 'user1' });
await doc.save();
const upsertResult = await UserModel
.findOneAndUpdate({}, { username: 'user1' }, {
upsert: true,
new: true,
rawResult: true
})
.exec();
console.log(doc);
}
main(); |
@IslandRhythms why remove the |
@hasezoey Val has told me that he only wants one label per issue so confirmed-bug overrides typescript. I do agree with you though. |
I think it is appropriate to have TypeScript label even if we also have "confirmed-bug" just to see what is a purely TypeScript issue. |
Can I work on this issue? |
you can put in a PR if you want to, i am not aware of anyone actively working on this yet probably the easiest would be to change the hooks for which functions return a |
Okay! I'll check the code. |
@hasezoey, after reviewing the Mongoose hook TypeScript declaration, I've noticed that Mongoose returns the document in hooks as the any type. (Mongoose 7.5) The problem mentioned by @FullStackSteve is related to the types defined in the Typegoose library, specifically at this line. To resolve this issue, you have a few possible solutions:
Now after the checking out the Typegoose Issue , I know you already knew about the above details. Should I implement 3rd solution in typegoose library and create a PR? |
from what i can tell, yes this could be fixed by typegoose, but mongoose also has some types which could be changed, for example (for 7.5 & 8.0): post<T = Query<any, any>>(method: MongooseDistinctQueryMiddleware|MongooseDistinctQueryMiddleware[], options: SchemaPostOptions, fn: PostMiddlewareFunction<T, QueryResultType<T>>): this; could be changed to something like post<T = Query<any, any>>(method: MongooseDistinctQueryMiddleware|MongooseDistinctQueryMiddleware[], options: SchemaPostOptions, fn: PostMiddlewareFunction<T, QueryResultType<T> | ModifyResult<QueryResultType<T>>>): this; (would require separating out the function that return though that would likely not change the default type from "any" because of the default UserSchema.post<
mongoose.Query<mongoose.HydratedDocument<mongoose.InferSchemaType<typeof UserSchema>>, mongoose.InferSchemaType<typeof UserSchema>>
> would then give the doc: (mongoose.Document<unknown, {}, {
id?: string | null | undefined;
username?: string | null | undefined;
}> & {
id?: string | null | undefined;
username?: string | null | undefined;
} & {
...;
}) | mongoose.ModifyResult<...> (and according errors) |
@hasezoey I got your point. This can be useful if user provides a custom type.
Is this related to separating the ModifyResult<> type if rawResult is found in query options because query options are not accessible in hooks. Also, anyways user will have to add a manual check for "value" to differentiate between the ModifyResult<> and Document in the callback function. Is there anyway that can be avoided or improved? From what I gather, my current understanding is that I need to add ModifyResult in the post hooks that supports |
i dont quite know what you are asking, i mean separating out things like
to my knowledge this cannot be avoided, and the only known ways of dealing with this are:
the last 2 options (assert and if-blocks) could be slightly improved by adding a helper function to detect if it is actually a ModifyResult instead of something else, that would need to be a bit more involved, because the passed-in object (read document) could also have its own |
Prerequisites
Mongoose version
~7.4.4
Node.js version
v16.19.1
MongoDB server version
4.0
Typescript version (if applicable)
~11.4.1
Description
Initially reported here typegoose/typegoose#886 and recommended to post here re: comment:
Incorrect types for the doc in the post findOneAndUpdate middleware when rawResult: true is set as option to the model.findOneAndUpdate(...) method
Steps to Reproduce
In typegoose:
Roughly the mongoose equivalent:
Expected Behavior
The middleware should return the correct types for the
doc
parameter when therawResult: true
parameter is passed so that this change can be reflected in the typegoose libraryThe text was updated successfully, but these errors were encountered: