Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[@types/mongodb] Generic TSchema type not accepted by insert methods #46375

Closed
g-pascal opened this issue Jul 27, 2020 · 10 comments
Closed

[@types/mongodb] Generic TSchema type not accepted by insert methods #46375

g-pascal opened this issue Jul 27, 2020 · 10 comments

Comments

@g-pascal
Copy link

Hi, I'm trying to build a generic Typescript DAO on top of mongodb, but I can't figure if the typings are simply incompatible with generic TSchema types, or if I'm doing something wrong.

A simple example:

import { Collection, MongoClient, ObjectId } from 'mongodb';
export class AbstractDao<T extends { _id: ObjectId }> {
    private mongoClient: MongoClient;

    public async create(entity: T): Promise<void> {
        const collection: Collection<T> = this.mongoClient.db('test-db').collection('test-collection');

        // Argument of type 'T' is not assignable to parameter of type 'OptionalId<T>'.
        // Type '{ _id: ObjectId; }' is not assignable to type 'OptionalId<T>'.
        await collection.insertOne(entity);
    }
}

I'm expecting Collection.insertOne to accept entity, but I can't get T extends { _id: ObjectId } to be accepted as a valid OptionalId<T>. I tried various constraints for T but I never got this class to compile.

@g-pascal
Copy link
Author

So I've dug into it and it boils down to my T extends { _id: ObjectId } not being assignable to the OptionalId<TSchema> expected by Collection.insertOne, because OptionalId is defined as a conditional type, in which type constraints are not resolved because of a language limitation better explained in this typescript issue.

I'm not sure exactly what case the OptionalId type is meant to handle, I think it's trying to enforce that the type of the _id property of an OptionalId<TSchema> must either be typeof TSchema['_id'] if it exists, or ObjectId otherwise?

The previous definition of OptionalId (before the commit e19dc99) worked well with generic TSchema types, because it did not use a conditional type, so TSchema constraints were properly resolved. But it did not enforce any specific type for the _id property in OptionalId, so that's a tradeoff.

@CaselIT
Copy link
Contributor

CaselIT commented Jul 28, 2020

Since the issue in typescript seems to be by design I think we could revert the OptionalId definition to the previous one. Could you open a pr for it?

@HosseinAgha
Copy link
Contributor

@CaselIT @g-pascal
Please also take look at this issue before merging anything: #39358
IMHO opening up the types for a special very abstract/generic use case usually results in more runtime bugs.

@dattannguyen
Copy link

dattannguyen commented Oct 22, 2020

Hi @HosseinAgha, I came here after reading #39358 and your issue on microsoft/TypeScript#35647, also microsoft/TypeScript#35077.

TypeScript said it works as expected so they have nothing to do, it brings the matter back to @types/mongodb. So now we just do workarounds, e.g {} as FilterQuery<Schema> or do you have any plan to fix in @types/mongodb?

@mariocalin
Copy link

Same here. Trying also to create a generic DAO.

@ravshansbox
Copy link

Experiencing the same problem. Any plans on resolving the issue?

@wuriyanto48
Copy link

try this

`collection.insertOne(entity as any);`

@adriana47
Copy link

Just ran into the same problem. Can't work without type safety in a strict codebase. Casting it as any or unknown is a dangerous and ugly workaround. The PR above has been abandoned, any chance of reopening?

@LinusU
Copy link
Contributor

LinusU commented Jul 24, 2023

The @types/mongodb packages has been removed and typings are now shipped upstream as part of the mongodb package, so this issue can be closed...

@peterblazejewicz
Copy link
Member

Closing as per last comment, thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

10 participants