TypeScript如何实现返回泛型标记接口的TResponse类型的函数?
问题解答
关于接收两个同类型IRequest<TResponse>参数并返回TResponse的函数
完全可以编写这样的函数,TypeScript的泛型系统支持从输入参数中自动推断对应的TResponse类型。示例如下:
interface IRequest<TResponse> { name: string; } function combineRequests<T>(req1: IRequest<T>, req2: IRequest<T>): T { // 这里可添加请求合并或API调用逻辑 return {} as T; // 示例返回值,实际需替换为业务逻辑结果 } // 使用示例 class BarResponse {} class BarRequest implements IRequest<BarResponse> { name = "bar"; } const req1 = new BarRequest(); const req2 = new BarRequest(); const result = combineRequests(req1, req2); // result类型为BarResponse
修复你的getResponse函数返回类型为unknown的问题
你的代码中,TypeScript无法自动推断泛型参数U的具体类型,导致返回类型变为unknown。核心原因是原泛型约束<T extends IRequest<U>, U>没有明确告诉TypeScript如何从T(即Foo类)中提取对应的响应类型U(即FooResponse)。
修正后的代码
interface IRequest<T> { name: string; } class FooResponse {} class Foo implements IRequest<FooResponse> { name = 'foo'; key1?: string; key2?: string; } // 辅助类型:从IRequest实现类中提取响应类型 type ExtractResponse<T extends IRequest<any>> = T extends IRequest<infer U> ? U : never; function getResponse<T extends IRequest<any>>(t: new () => T, args: Partial<T>): ExtractResponse<T> { const obj = new t(); Object.assign(obj, args); console.log(obj); // 模拟API调用返回对应类型结果 return {} as ExtractResponse<T>; } const value = getResponse(Foo, { key1: 'bar' }); // value类型现在为FooResponse
解决原理
- 辅助类型
ExtractResponse:使用infer U关键字,让TypeScript自动推断出T实现的IRequest接口对应的泛型参数U,也就是我们需要的响应类型。 - 简化泛型参数:仅保留一个泛型参数
T,TypeScript通过传入的构造函数推断出T的具体类型(即Foo),再通过辅助类型提取出FooResponse作为返回类型。
这样调用getResponse(Foo, ...)时,TypeScript就能正确识别返回类型为FooResponse,而非unknown。
内容的提问来源于stack exchange,提问作者Adam Bross
相关产品推荐
相关产品推荐

