You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用MongoDB Node.js的updateOne方法时出现TypeScript编译时错误

Fixing TypeScript Error 2769 with Mongoose updateOne

Let's walk through what's causing this compilation error and fix it step by step:

What's Going Wrong?

Your TS error code 2769 stems from two key issues:

  1. Incorrect updateOne usage: Mongoose's updateOne requires two core arguments: first a filter to target the specific document you want to update, then the update payload. Right now you're only passing the update fields, so TypeScript is treating that object as the filter (which doesn't match the expected type for your user model).
  2. Type mismatch from optional chaining: Your code uses updatePayLoad.data?.firstName, which makes those fields string | undefined. But your Mongoose model defines firstName/lastName as required string fields, and with exactOptionalPropertyTypes: true enabled, TypeScript blocks assigning undefined to non-optional properties.

Additionally, your Zod schema marks all three fields as required—if this is a partial update endpoint (where users can update just one or two fields), that schema needs adjustment too.

Step-by-Step Fixes

1. Correct the updateOne Parameter Order

First, add a filter to target the specific user you want to update (like their _id or email). Here's the proper structure:

// Example: Use user ID as the filter (adjust based on how you identify users)
const response = await userModel.updateOne(
  { _id: userId }, // 1. Filter: Which user should be updated?
  { 
    firstName: updatePayLoad.data.firstName,
    lastName: updatePayLoad.data.lastName,
    password: hashedPassword 
  }, // 2. Update: What fields to modify?
  { new: true } // Optional: Return the updated document instead of the original
);

2. Resolve the undefined Type Issue

Since you're using Zod for validation, leverage it to guarantee your fields aren't undefined:

// First, validate the payload with your Zod schema
const validatedData = updateValidation.parse(updatePayLoad.data);

// Now validatedData has guaranteed string values (no undefined)
const hashedPassword = await bcrypt.hash(validatedData.password, 10); // Adjust hashing logic as needed

const response = await userModel.updateOne(
  { _id: userId },
  {
    $set: { // Using $set is Mongoose's recommended way to update specific fields
      firstName: validatedData.firstName,
      lastName: validatedData.lastName,
      password: hashedPassword
    }
  }
);

If this is a partial update endpoint (allowing users to skip some fields), modify your Zod schema to make fields optional, then filter out undefined values:

// Update Zod schema for partial updates
export const updateValidation = z.object({ 
  firstName: z.string().optional(), 
  lastName: z.string().optional(), 
  password: z.string().optional() 
});

// Validate and filter out undefined fields
const validatedData = updateValidation.parse(updatePayLoad.data);
const updateFields = Object.fromEntries(
  Object.entries(validatedData).filter(([_, value]) => value !== undefined)
);

// Add hashed password if it's provided (or make it required if needed)
if (validatedData.password) {
  updateFields.password = await bcrypt.hash(validatedData.password, 10);
}

// Run the update
const response = await userModel.updateOne(
  { _id: userId },
  { $set: updateFields }
);

If you want a quick fix without changing code, you can disable exactOptionalPropertyTypes in your tsconfig.json—but this removes a useful type safety check, so fixing the code is the better long-term solution:

{
  "compilerOptions": {
    "exactOptionalPropertyTypes": false
  }
}

Final Working Example (Full Update)

Here's a clean version assuming you're requiring all three fields:

import { updateValidation } from "../your-schema-path";
import bcrypt from "bcrypt";

// Inside your route handler
const validatedData = updateValidation.parse(req.body.data); // Adjust based on your payload structure
const hashedPassword = await bcrypt.hash(validatedData.password, 10);

const updatedUser = await userModel.updateOne(
  { _id: req.user.id }, // Assume you get the user ID from auth middleware
  {
    $set: {
      firstName: validatedData.firstName,
      lastName: validatedData.lastName,
      password: hashedPassword
    }
  },
  { new: true }
);

res.status(200).json(updatedUser);

内容的提问来源于stack exchange,提问作者Adarsh Singh

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 06:39:40