TypeScript异步包装泛型函数返回类型与直接返回不一致问题
问题原因
- TypeScript 处理未实例化泛型的条件类型时,不会延迟分支判断,会优先使用条件类型的 fallback 分支做类型推导。
- 你定义的
CheckSelect<T, S, U>是条件类型,在wrapperNotWorking的泛型函数作用域内,T还没有被具体类型填充,TypeScript 无法判断命中哪个分支,会直接取最后一个 fallback 分支的Promise<1>类型,await解包后得到类型1,这就是返回类型始终为1的根因。 - 而
wrapperWorking直接透传findMany的返回值,TypeScript 不会提前解析条件类型,会把完整的CheckSelect类型保留到函数调用、T被实例化的时候再判断,所以推导正确。
解决方案
针对你需要加异步前后置操作的封装场景,不需要手动声明返回类型、也不需要类型强转的实现方案如下:不返回await后的结果,直接返回findMany的原始返回值,前后置操作可以正常执行,类型会自动透传:
async function wrapFindMany<T extends {select?: string, include?: string}>(args: T){ await doSomethingBefore(args); // 先拿到findMany的原始返回值(包含完整条件类型) const rawResult = findMany(args); // 正常await做后续操作 const resolvedResult = await rawResult; await doSomethingAfterwards(resolvedResult); // 直接返回原始的rawResult,而非await后的resolvedResult return rawResult; }
这个方案的原理是:返回原始的rawResult时,TypeScript 会透传findMany的完整条件类型,不会提前解析分支,async函数会自动对返回值做Promise解包,最终得到的返回类型和直接调用findMany完全一致,符合预期。
内容的提问来源于stack exchange,提问作者ysfaran
相关产品推荐
相关产品推荐

