Would it be possible for the MongoDB Node.js driver to extract the correct "projection" type?

Let’s say I have a collection of documents:

{
  "foo": string;
   "nested": { "prop1": number,  "prop2": string}
}

And I make a query in Typescript with this projection

col.findOne({}, {foo: 1,  "nested.prop1": 1})

Would it somehow be possible for the driver to infer the correct type, i.e.

{
  "foo": string,
  "nested": {
    "prop1": number
  }
}

Or is it simply not possible?

1 Like

Currently, the MongoDB driver for TypeScript cannot automatically infer the types resulting from a projection in the query, but you can manually define types to ensure that TypeScript correctly understands the shape of the returned data.

Here is an example of how you can do this:

  1. Define an interface for the complete document:
interface Document {
  foo: string;
  nested: {
    prop1: number;
    prop2: string;
  };
}
  1. Define an interface for the projected document:
interface ProjectedDocument {
  foo: string;
  nested: {
    prop1: number;
  };
}

Example:

import { MongoClient } from 'mongodb';

async function run() {
  const client = new MongoClient('your_mongodb_connection_string');
  await client.connect();
  const database = client.db('your_database_name');
  const collection = database.collection<Document>('your_collection_name');

  const result = await collection.findOne<Partial<ProjectedDocument>>({}, {
    projection: { foo: 1, 'nested.prop1': 1 }
  });

  console.log(result);
}

run().catch(console.dir);

By defining the interfaces and using Partial<ProjectedDocument>, you are informing TypeScript that the result will be a subset of the ProjectedDocument interface, which allows you to obtain the correct type inference for the projected fields.

2 Likes

Hi @Samuel_84194 , 100% - and this is also how we do it in our team (actually we just use the nice utility DeepPick from ts-essentials).

But this approach is very fragile because if someone updates one and not the other it’s out of sync.

I imagine this is something all MongoDB typescript developers would hugely benefit from if the projected type could somehow be derived.

So the question stands for the typescript experts; is it a solvable problem?

1 Like

Just chiming in here to say, that we also experience this as a bit fragile. It would be nice to have a way of keeping the interface and projections in sync.

@alexbevi is this something that you have experimented with? It would be the best new feature for the driver since sliced bread :smiling_face: