Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

let generic function match another function's specific overload signature

Try to write a generic function to match the second overload signature of findOne() method of Collection class.

import { Document, Filter, FindCursor, FindOptions, MongoClient, WithId } from 'mongodb'; // tags: ^5.6.0

const uri = '<connection string uri>';
const client = new MongoClient(uri);

function findUsers<TSchema extends Document = Document>(
    find_pattern: Filter<TSchema>,
    options?: FindOptions,
): FindCursor<WithId<TSchema>> {
    return client.db('main').collection('accounts').find(find_pattern, options);
}

The overload signatures of findOne():

export declare class Collection<TSchema extends Document = Document> {
    //...
    find(): FindCursor<WithId<TSchema>>;
    find(filter: Filter<TSchema>, options?: FindOptions): FindCursor<WithId<TSchema>>;
    find<T extends Document>(filter: Filter<TSchema>, options?: FindOptions): FindCursor<T>;
    //...
}

Try to match below overload signature.

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

find(filter: Filter<TSchema>, options?: FindOptions): FindCursor<WithId<TSchema>>;

TSC throws two errors, the first error throws at the return keyword.

Type 'FindCursor<WithId<Document>>' is not assignable to type 'FindCursor<WithId<TSchema>>'.
  Type 'WithId<Document>' is not assignable to type 'WithId<TSchema>'.
    Type 'WithId<Document>' is not assignable to type 'EnhancedOmit<TSchema, "_id">'.(2322)

The second error throws at the .find(find_pattern, options).

No overload matches this call.
  Overload 1 of 3, '(filter: Filter<Document>, options?: FindOptions<Document> | undefined): FindCursor<WithId<Document>>', gave the following error.
    Argument of type 'Filter<TSchema>' is not assignable to parameter of type 'Filter<Document>'.
      Type 'Filter<TSchema>' is not assignable to type 'RootFilterOperators<WithId<Document>>'.
        Types of property '$and' are incompatible.
          Type 'Filter<WithId<TSchema>>[] | undefined' is not assignable to type 'Filter<WithId<Document>>[] | undefined'.
            Type 'Filter<WithId<TSchema>>[]' is not assignable to type 'Filter<WithId<Document>>[]'.
              Type 'Filter<WithId<TSchema>>' is not assignable to type 'Filter<WithId<Document>>'.
                Type 'Filter<WithId<TSchema>>' is not assignable to type 'RootFilterOperators<WithId<WithId<Document>>>'.
                  Types of property '$where' are incompatible.
                    Type 'string | ((this: WithId<WithId<TSchema>>) => boolean) | undefined' is not assignable to type 'string | ((this: WithId<WithId<Document>>) => boolean) | undefined'.
                      Type '(this: WithId<WithId<TSchema>>) => boolean' is not assignable to type 'string | ((this: WithId<WithId<Document>>) => boolean) | undefined'.
                        Type '(this: WithId<WithId<TSchema>>) => boolean' is not assignable to type '(this: WithId<WithId<Document>>) => boolean'.
                          The 'this' types of each signature are incompatible.
                            Type 'WithId<WithId<Document>>' is not assignable to ty

Playground Link

package versions:

"typescript": "^5.1.6",
"mongodb": "^5.6.0"

>Solution :

In the findOne overloads, it doesn’t accept TSchema, but the Document:

export declare class Collection<TSchema extends Document = Document> {
    //...
    find(): FindCursor<WithId<TSchema>>;
    find(filter: Filter<TSchema>, options?: FindOptions): FindCursor<WithId<TSchema>>;
    find<T extends Document>(filter: Filter<TSchema>, options?: FindOptions): FindCursor<T>;
    //...
}

The TSchema is accepted by the Collection class, thus you can fix it just by passing your schema to the collection method:

function findUsers<TSchema extends Document = Document>(
    find_pattern: Filter<TSchema>,
    options?: FindOptions,
): FindCursor<WithId<TSchema>> {
    return client.db('main').collection<TSchema>('accounts').find(find_pattern, options);
}

Link to Playground

Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading