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
相关产品推荐
相关产品推荐

