TypeScript重载函数typeof区分:获取Mongoose.Model.find指定参数类型
解决TypeScript中获取重载函数特定版本参数类型的问题(Mongoose场景)
在Mongoose+TypeScript项目里,用Parameters<typeof Model.find>提取参数类型时,总会拿到最后一个带回调的重载版本的参数,而不是想要的第三个重载的FilterQuery相关类型——这是因为TypeScript的Parameters工具类型默认只会取重载函数的最后一个签名,官方相关Issue至今未解决。下面是几个实用的解决办法:
1. 手动构造目标重载的参数类型
直接参考Mongoose的类型定义,手动写出目标重载的参数结构。比如Model.find的第三个重载参数是可选的筛选器、投影和查询选项,对应的类型可以直接定义:
import { FilterQuery, ProjectionType, QueryOptions } from 'mongoose'; type FindThirdOverloadParams<T> = [FilterQuery<T>?, ProjectionType<T>?, QueryOptions<T>?];
这种方式简单直接,不需要依赖Parameters,完全避免重载匹配的问题。
2. 断言函数为目标重载类型后提取参数
先定义出目标重载的函数类型,再把Model.find断言成这个类型,最后用Parameters提取参数:
import { Model, FilterQuery, ProjectionType, QueryOptions, Query } from 'mongoose'; // 定义第三个重载的函数类型 type TargetFindOverload<T> = ( filter?: FilterQuery<T>, projection?: ProjectionType<T>, options?: QueryOptions<T> ) => Query<T[], T>; // 断言后提取参数 type FindThirdParams<T> = Parameters<TargetFindOverload<T>>;
这样既保留了Parameters的使用习惯,又绕过了TypeScript默认取最后一个重载的限制。
3. 自定义工具类型提取指定索引的重载
自己实现一个工具类型,用来精准获取重载函数的第N个签名的参数类型。针对Model.find的4个重载,可以这么写:
// 自定义工具类型,支持最多4个重载的函数,N为重载索引(从0开始) type OverloadParams<T, N extends number> = T extends { (...args: infer A0): any; (...args: infer A1): any; (...args: infer A2): any; (...args: infer A3): any; } ? N extends 0 ? A0 : N extends 1 ? A1 : N extends 2 ? A2 : N extends 3 ? A3 : never : never; // 使用时,取第三个重载(索引为2) type FindThirdParams = OverloadParams<typeof FooModel.find, 2>;
注意如果后续Mongoose更新了find的重载数量,需要同步调整这个工具类型里的分支数量。
内容的提问来源于stack exchange,提问作者HADMARINE
相关产品推荐
相关产品推荐

