简化从对象提取多函数返回值联合类型的ReturnType写法
提取对象中多个指定函数的返回值联合类型
嘿,这个场景我太熟悉了——每次重复写typeof actions确实有点啰嗦,其实咱们可以通过自定义可复用的类型工具或者组合内置类型来搞定,两种方式都能避免重复代码,先看最简洁好用的方案:
方案一:自定义可复用的类型工具
先写一个通用的类型,专门用来提取对象中指定键对应的函数返回值:
// 自定义类型:从对象T中提取指定键K对应的函数的返回值联合类型 type PickReturnTypes<T, K extends keyof T> = T[K] extends (...args: any[]) => infer R ? R : never;
然后用你的例子来测试:
const actions = { success: () => true, count: () => 0, failure: () => "error" }; // 提取success和failure函数的返回值联合类型 type AvailableValues = PickReturnTypes<typeof actions, 'success' | 'failure'>; // 最终类型:boolean | string
这个类型的逻辑很直白:
T是原对象的类型,K是你要筛选的键的联合类型(必须是T的键)- 通过
T[K]拿到指定键对应的函数类型,再用条件类型+infer自动提取函数的返回值R - 最后所有符合条件的返回值会自动组成联合类型
方案二:组合内置类型(无需自定义)
如果不想额外写自定义类型,也可以直接组合Pick、keyof和ReturnType来实现:
type AvailableValues = ReturnType< Pick<typeof actions, 'success' | 'failure'>[keyof Pick<typeof actions, 'success' | 'failure'>] >; // 同样得到:boolean | string
这里的逻辑是:
Pick<typeof actions, 'success' | 'failure'>先拿到包含指定函数的子对象类型keyof Pick<...>拿到这个子对象的键联合类型,再通过索引访问Pick<...>[keyof Pick<...>]得到所有指定函数的类型联合- 最后用
ReturnType提取每个函数的返回值,组成最终的联合类型
不过这种写法虽然不用自定义类型,但重复写了两次Pick<...>,如果要选的键很多,还是自定义类型工具更清爽。
为什么之前的Pick单独用不行?
你提到的Pick<typeof actions, 'success' | 'failure'>得到的是对象类型(比如{ success: () => boolean; failure: () => string; }),而不是函数类型的联合,所以没法直接用ReturnType。我们需要先把对象里的函数类型“取出来”变成联合类型,再提取返回值——这就是上面两种方案的核心思路。
内容的提问来源于stack exchange,提问作者Explosion Pills




