Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Casting Mongodb Document to Typescript Interface

In my typescript express app, I am trying to retrieve a document from mongoDB and then cast that document to a type defined by an interface.

const goerPostsCollection = databaseClient.client.db('bounce_dev1').collection('goerPosts');
var currentGoerPosts = await goerPostsCollection.findOne({ goerId: currentUserObjectId }) as GoerPosts;
if (!currentGoerPosts) {
    currentGoerPosts = CreateEmptyGoerPosts(currentUserObjectId);
}

and the interface is defined like this

export interface GoerPosts {
    goerId: ObjectId;
    numPosts: number;
    posts: ObjectId[];
};

The code above has been working for me until I updated typescript from 4.4.4 to 4.5.2. Now the code no longer works and I get the error message:

[ERROR] 03:30:48 ⨯ Unable to compile TypeScript:
[posts] src/routes/create-post.ts(37,28): error TS2352: Conversion of type 'WithId<Document> | null' to type 'GoerPosts' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
[posts]   Type 'WithId<Document>' is missing the following properties from type 'GoerPosts': goerId, numPosts, posts

I can probably just revert back to 4.4.4, but I am wondering if there is a better way to do this cleanly going forward.

like image 759
Sebby Fay Avatar asked Dec 05 '25 21:12

Sebby Fay


1 Answers

I had an issue with this too. The toArray() function returns a WithId<Document> type. You can extend this interface to get typescript to work.

import type { WithId, Document } from 'mongodb'

interface GoerPosts extends WithId<Document> {
    goerId: ObjectId;
    numPosts: number;
    posts: ObjectId[];
}

var currentGoerPosts = (await goerPostsCollection.findOne({ goerId: currentUserObjectId }).toArray()) as GoerPosts;

2022 Update

You can pass the type to the collection

export interface GoerPosts {
    goerId: ObjectId;
    numPosts: number;
    posts: ObjectId[];
};

const currentGoerPosts = databaseClient.client.db('bounce_dev1').collection<GoerPosts>('goerPosts').findOne({ goerId: currentUserObjectId });

This will return WithId<GoerPosts> without the need to extend the WithId interface

like image 77
Trevor V Avatar answered Dec 08 '25 13:12

Trevor V



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!