DEV Community

Cover image for What I Learned Last Week: TypeScript, MongoDB Cursors, and checking MongoDB Ids
Devjam247
Devjam247

Posted on

What I Learned Last Week: TypeScript, MongoDB Cursors, and checking MongoDB Ids

 Last week, I ran into a frustrating problem where comparing MongoDB product IDs as strings kept failing. I also realized I had a misunderstanding about TypeScript—I thought it somehow made my code run faster or changed the way the browser executed it. Both confusions made me feel like I was missing something basic.

Things finally clicked when I understood that TypeScript only exists during development to catch errors and that MongoDB's find() method doesn't return all documents at once but instead gives a cursor that we can iterate over or convert to an array with toArray(). Realizing this clarified both why my ID comparisons were failing and why TypeScript wasn't changing runtime behavior.

I like to think of TypeScript as a friend sitting behind me while I code, quietly pointing out mistakes in real time. It tells me if an object doesn't match the expected interface, without changing what actually happens when I run the code. MongoDB cursors feel like a conveyor belt—rather than dumping millions of items at once, they let me pick each document one by one or take a batch when I need it.

Understanding this matters because TypeScript helps prevent subtle bugs by checking that objects have the expected structure, and working with cursors avoids performance issues when handling large datasets. It also ensures I don’t mistakenly compare ObjectId values as strings, which can cause confusing runtime errors.

In practice, TypeScript just compiles down to regular JavaScript:

interface Todo {
  id: number;
  title: string;
  completed: boolean;
}
const todo = response.data as Todo;
Enter fullscreen mode Exit fullscreen mode

It helps during development but has no effect on runtime. With MongoDB, fetching all products requires working with a cursor:

const productsCursor = db.collection("products").find();
const products = await productsCursor.toArray();
Enter fullscreen mode Exit fullscreen mode

Fetching a single product by ID also requires converting a string to an ObjectId:

const product = await db.collection("products")
  .find({ _id: new mongodb.ObjectId(prodId) })
  .next();
Enter fullscreen mode Exit fullscreen mode

Some common mistakes I nearly made include assuming TypeScript changes runtime behavior, forgetting to call toArray() on a cursor, comparing ObjectId values as strings, or expecting find() to return a promise directly.

One concrete example from my notes illustrates this:

static findById(prodId) {
  const db = getDb();
  return db
    .collection("products")
    .find({ _id: new mongodb.ObjectId(prodId) })
    .next()
    .then(product => {
      console.log(product);
      return product;
    })
    .catch(err => console.log(err));
}
Enter fullscreen mode Exit fullscreen mode

This example shows how to correctly handle cursors and ObjectId comparisons.

Key takeaways from this week:

  • TypeScript only helps during development; it does not change runtime behavior.
  • Think of TypeScript as a helpful friend pointing out type mismatches.
  • MongoDB find() returns a cursor, not all documents at once.
  • Use toArray() to fetch items or iterate step by step.
  • Always compare MongoDB IDs using ObjectId, not strings.

I’m realizing that learning these tools is more about understanding what they don’t do as much as what they do. Recognizing their boundaries makes coding less mysterious and prevents unnecessary frustration, and that itself feels like progress.

Top comments (0)