TypeScript:基于泛型输入的动态返回类型(含默认值)问题
TypeScript 5.7.2 实现动态返回类型的函数定义问题
原代码与问题
定义了一个根据参数动态返回结果的函数类型:
type ServiceFunction = <RD extends object, RR extends boolean = false>(args: { returnResponse?: RR; }) => RR extends true ? Promise<RD> : void;
声明函数:
declare const getEvents: ServiceFunction;
尝试按如下方式调用时:
const events = getEvents<{ events: string[] }>({ returnResponse: true });
出现TypeScript错误:
Type 'true' is not assignable to type 'false'. The expected type comes from property 'returnResponse' which is declared here on type '{ returnResponse?: false | undefined; }'
问题根源:给泛型RR设置默认值false后,当手动指定第一个泛型参数RD时,RR会直接使用默认值false,导致returnResponse的类型被限制为false | undefined,无法传入true。
期望行为
- 传入
returnResponse: true时,返回类型为Promise<{ events: string[] }> - 传入
returnResponse: false或省略该属性时,返回类型为void
解决方案(TypeScript 5.7.2 支持)
使用函数重载可以完美实现需求,既不用手动指定第二个泛型参数,又能让TypeScript根据传入的参数自动推断返回类型:
// 定义重载类型 type ServiceFunction = // 重载1:不传returnResponse或传false,返回void <RD extends object>(args?: { returnResponse?: false | undefined }) => void // 重载2:传returnResponse: true,返回Promise<RD> & <RD extends object>(args: { returnResponse: true }) => Promise<RD>; // 声明函数 declare const getEvents: ServiceFunction; // 测试调用 // 1. 传returnResponse: true,返回Promise<{ events: string[] }> const events = getEvents<{ events: string[] }>({ returnResponse: true }); // 2. 传returnResponse: false,返回void const result1 = getEvents({ returnResponse: false }); // 3. 省略returnResponse,返回void const result2 = getEvents(); const result3 = getEvents({});
这种方式下,TypeScript会根据传入的returnResponse值自动匹配对应的重载,同时允许你手动指定数据结构泛型RD,完全符合需求。
内容的提问来源于stack exchange,提问作者Shannon Hochkins
相关产品推荐
相关产品推荐

