MongoDB Filter between two dates
Prefer dot notation over bracket notation when syntax permits it - it's a bit easier to read and write. ESLint rule: dot-notation.
Construct objects all in one go rather than mutating them afterwards, if you can - it's easier to write (especially in TypeScript, since you don't have to denote the type ahead of time) and can be easier to understand at a glance when unnecessary mutation is avoided.
Don't assign expressions that won't be used - with
let reportsForContent: Report[] = [];

regardless of the situation, reportsForContent will be reassigned to something else afterwards, so you can leave off the = [] part.
Or, even better:
Return the value retrieved instead of reassigning a variable and then returning the variable. This:
  if (beginDate || endDate) {
    reportsForContent = await reportsCollection.find({ contentId, creationDate: creationDateMongoFilter }).toArray();
  } else {
    reportsForContent = await reportsCollection.find({ contentId }).toArray();
  }

can be
  if (beginDate || endDate) {
    return reportsCollection.find({ contentId, creationDate: creationDateMongoFilter }).toArray();
  } else {
    return reportsCollection.find({ contentId }).toArray();
  }

Or, even better, handle the case where no date is set at the very beginning, and only construct the creationDateMongoFilter later, if it's needed.
In all:
export const getReportsForContent = async (
    contentId: ObjectId,
    beginDate: Date | undefined,
    endDate: Date | undefined,
): Promise&lt;Report[]&gt; =&gt; {
    const reportsCollection = await getCollection('reports');
    if (!beginDate &amp;&amp; !endDate) {
        return reportsCollection.find({ contentId }).toArray();
    }
    const creationDateMongoFilter = {
        (...beginDate &amp;&amp; { $gte: beginDate }),
        (...endDate &amp;&amp; { $lte: endDate }),
    };
    return reportsCollection.find({ contentId, creationDate: creationDateMongoFilter }).toArray();
};

No need for the mongoDateFilter interface anymore.