findByupIdAndUpdate – update only fields that are provided

I have this mutation editItem that is used for editing of an item:

{
  "data": {
    "addItem": {
      "id": "623720fafdb2581bb7e0b41e",
      "itemDate": "2022-03-20T13:41:30",
      "itemName": "item",
      "itemCategory": {
        "categoryName": "item",
        "categoryType": "category"
      },
      "itemPrice": {
        "price": "100",
        "currency": "GBP"
      },
      "itemUpdated": {
        "isUpdated": false,
        "updatedBy": null,
        "updateStamp": null
      },
      "createdBy": {
        "username": "username",
        "name": "Name",
        "date": "2022-03-20T12:41:30.132"
      }
    }
  }
}

Mutation code:

type Mutation {
   editItem(itemID: ID!, itemInput: ItemInput): Item!
}

editItem: async (_, args, context) => {
      const currentUser = await checkAuthorization(context)
      let { itemDate, itemName, itemCategory, itemPrice, itemUpdated } =
        args.itemInput

      if (itemDate) {
        itemDate = dayjs(itemDate).format('YYYY-MM-DDTHH:mm:ss')
      }
      if (itemPrice) {
        itemPrice = { ...itemPrice, price: itemPrice.price }
      }
      if (itemCategory) {
        itemCategory = {
          ...itemCategory,
          categoryType: itemCategory.categoryType,
        }
      }
      if (itemDate || itemName || itemCategory || itemPrice) {
        const currentDate = dayjs(new Date()).format('YYYY-MM-DDTHH:mm:ss')
        itemUpdated = {
          ...itemUpdated,
          isUpdated: true,
          updatedBy: currentUser.username,
          updateStamp: currentDate,
        }

        const itemBody = await Item.findByIdAndUpdate(
          args.itemID,
          {
            $set: {
              itemDate: itemDate,
              itemName: itemName,
              'itemCategory.categoryName': itemName,
              'itemCategory.categoryType': itemCategory.categoryType,
              'itemPrice.price': itemPrice.price,
              itemUpdated: itemUpdated,
            },
          },
          { upsert: true, new: true },
        )
        return itemBody
      }
    },

Let’s say that I need to edit only itemDate, so I send a request accordingly

{
  "itemId": "623624d0eb73fc77853c520b",
  "itemInput": {
    "itemDate": "2022-03-01"
  }
}

However, I’m getting an error referring to the editItem mutation:

"message": "Cannot read properties of undefined (reading 'categoryType')",

So it seems that the $set request requires all fields to be filled in. When all are provided in the request, it works just fine.

I tried to do it similarly without using the $set, however then it would just overwrite the not provided fields to null.
Is the findByIdAndUpdate not suitable for this activity or what do I need to do to achieve $set not requiring everything to be provided?