You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript交叉函数返回类型与推断类型不匹配问题求助

解决交叉类型中Promise返回类型推断不一致的问题

问题原因

你遇到的矛盾源于TypeScript对交叉函数类型的两种处理逻辑差异:

  • 直接用T extends () => Promise<infer T> ? T : null做条件类型推断时,TypeScript会取交叉类型中最后一个函数的返回类型作为结果;
  • 但实际调用交叉函数时,TypeScript会遵循函数兼容性规则,返回最具体的子类型(比如string是any的子类型,所以调用时始终返回string)。

解决方案

利用ReturnType<T>工具类型获取交叉函数实际调用时的返回类型,再从中提取Promise的泛型参数。ReturnType<T>会自动处理交叉函数的类型优先级,返回调用时的真实类型。

通用类型工具

// 提取交叉类型中json方法的Promise返回类型
type ExtractJsonReturnType<T> = 
  T extends { json: () => Promise<infer U> } 
    ? U 
    : never;

实际场景示例

// 模拟基础HTTPRequest类型
type HTTPRequest = {
  json: () => Promise<any>;
  // 其他请求属性,比如method、url等
};

// 带具体返回类型的交叉请求类型
type UserRequest = HTTPRequest & {
  json: () => Promise<{ id: number; username: string }>;
};

// 获取正确的JSON返回类型
type UserResponse = ExtractJsonReturnType<UserRequest>;
// UserResponse 类型为 { id: number; username: string }

验证原始示例

export {}
type Foo = (() => Promise<string>) & (() => Promise<any>);
type Foo2 = (() => Promise<any>) & (() => Promise<string>);

// 使用改进后的类型推断
type GetPromiseResult<T extends () => Promise<any>> = ReturnType<T> extends Promise<infer U> ? U : never;

type FooResult = GetPromiseResult<Foo>; // string
type FooResult2 = GetPromiseResult<Foo2>; // string

const a:Foo = async () => "";
const b = await a(); // b: string

const c:Foo2 = async () => "";
const d = await c(); // d: string

这样不管交叉类型的顺序如何,推断出的类型都和实际调用结果一致。

内容的提问来源于stack exchange,提问作者Kostas Xafis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.20 04:47:20