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.
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
package versions:
"typescript": "^5.1.6",
"mongodb": "^5.6.0"
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);
}