如何解决TypeScript中Omit移除字段后findOneAndUpdate的报错问题
Let's break down why you're seeing this error and how to fix it cleanly:
The Root Cause
You’ve correctly used Omit<AuthorInterface, "image" | "image_webp"> to exclude the image fields from your input parameter, but TypeScript is still complaining because when you spread { ...author } into the update object, it’s expecting the author field to match the full AuthorInterface type (as defined in UserModelInterface). Since your input lacks image and image_webp, TypeScript flags it as incomplete.
Solution 1: Use $set for Partial Updates (Recommended)
Mongoose’s findOneAndUpdate works best with $set when you only want to update specific fields—this also makes TypeScript happier because it understands you’re not replacing the entire author object, just updating parts of it.
public saveAuthor(_id: mongoose.Types.ObjectId | string, author: Omit<AuthorInterface, "image" | "image_webp">): Promise<UserModelInterface | null> { // Use $set to only update the provided author fields, leaving image/image_webp untouched return User.findOneAndUpdate( { _id }, { $set: { author } }, { new: true } // Return the updated document ).exec(); }
Solution 2: Type Assertion for Partial Objects
If you prefer not to use $set, you can explicitly tell TypeScript that your partial author object is acceptable by asserting it as Partial<AuthorInterface>:
public saveAuthor(_id: mongoose.Types.ObjectId | string, author: Omit<AuthorInterface, "image" | "image_webp">): Promise<UserModelInterface | null> { return User.findOneAndUpdate( { _id }, { author: { ...author } as Partial<AuthorInterface> }, { new: true } ).exec(); }
This works because Partial<AuthorInterface> marks all fields as optional, so TypeScript no longer expects image and image_webp to be present.
Solution 3: Define a Dedicated Update Type
For even clearer type safety, you can create a custom type for your author update input:
// Define exactly what fields are allowed for updates type AuthorUpdateData = Omit<AuthorInterface, "image" | "image_webp">; public saveAuthor(_id: mongoose.Types.ObjectId | string, author: AuthorUpdateData): Promise<UserModelInterface | null> { return User.findOneAndUpdate( { _id }, { $set: { author } }, { new: true } ).exec(); }
This makes your code more readable and enforces that only the intended fields can be passed in.
Key Takeaway
The main issue was TypeScript expecting a full AuthorInterface object for the update, but you’re only providing a subset. Using $set is the most idiomatic Mongoose approach here—it ensures you don’t accidentally overwrite the image fields, and it aligns with how TypeScript handles partial updates.
内容的提问来源于stack exchange,提问作者Ilijanovic

