编写rubico库fork函数的TypeScript类型定义时遇到问题求解
问题根因
你当前类型定义的问题出在 TypeScript 联合类型的 extends 判定规则:只有联合类型的所有成员都满足 extends 右侧的类型约束时,整个判定才会返回 true。当传入的对象中部分函数返回同步值、部分返回 Promise 时,ReturnType<IN[keyof IN]> 是「普通值 | Promise」的联合类型,自然不满足 extends Promise<any> 的条件,所以会错误推导为非 Promise 类型。
解决方案
新增一个分布式条件类型,判断联合类型中是否存在至少一个 PromiseLike 类型的成员,只要有一个符合就判定为需要返回 Promise:
type GenericFunction<OUT = any> = (...args: readonly any[]) => OUT; type Dict<T> = { [k: string]: T }; type Awaited<T> = T extends PromiseLike<infer U> ? Awaited<U> : T; // 分布式条件判断:只要联合类型中有一个是PromiseLike就返回true,否则返回false type HasAnyPromise<T> = (T extends PromiseLike<any> ? true : never) extends never ? false : true; declare function fork< IN extends Dict<GenericFunction>, OUT = { [k in keyof IN]: Awaited<ReturnType<IN[k]>> }, RS = ReturnType<IN[keyof IN]>, // 只要任意返回值是Promise就返回Promise<OUT>,否则返回OUT >(obj: IN): HasAnyPromise<RS> extends true ? Promise<OUT> : OUT;
效果验证
修改后三个测试用例都会正确推导:
res1所有函数返回同步值,推导类型为{ x: number, y: string }res2存在至少一个异步函数,推导类型为Promise<{ x: number, y: number }>res3所有函数返回异步值,推导类型为Promise<{ x: number, y: number }>
内容的提问来源于stack exchange,提问作者Daniel Farina
相关产品推荐
相关产品推荐

