TypeScript:编写泛型函数匹配Collection类find方法重载签名问题
解决MongoDB泛型find函数的类型错误问题
需求
编写一个泛型函数,匹配Collection类find方法的第二个重载签名:
find(filter: Filter<TSchema>, options?: FindOptions): FindCursor<WithId<TSchema>>;
现有代码
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); }
Collection类的find方法重载签名
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>; //... }
类型错误信息
- return语句错误:
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)
.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
环境版本
"typescript": "^5.1.6", "mongodb": "^5.6.0"
解决方案
问题根源在于调用collection('accounts')时未指定泛型类型,默认使用Document作为TSchema,导致后续find方法的类型推导与函数泛型参数TSchema不匹配。
修改代码,给collection指定泛型参数TSchema,让Collection实例的类型与函数泛型保持一致,即可正确匹配目标重载签名:
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>> { // 给collection指定泛型TSchema return client.db('main').collection<TSchema>('accounts').find(find_pattern, options); }
修改后,Collection实例的TSchema与函数泛型参数统一,find方法会正确匹配第二个重载签名,类型错误即可消除。
内容的提问来源于stack exchange,提问作者Lin Du
相关产品推荐
相关产品推荐

