Casting Mongodb Document to Typescript Interface

Viewed 2225

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.

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;
Related