You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何基于函数返回值筛选TypeScript接口中的函数键?

问题分析与解决

先明确核心问题:你写的KeysReturnStrings在传入单个键时正常,但传入keyof MyInterface这类联合类型时返回never,而前缀筛选的KeysNoGet却能处理联合类型,本质是条件类型的分布式行为差异导致的。

为什么原写法失效

当你把联合类型keyof MyInterface传入KeysReturnStrings时,ReturnType<MyInterface[K]>会直接计算成所有返回值的联合类型string | number。此时判断string | number extends string?显然不成立,所以整个条件返回never。

而KeysNoGet能正常工作,是因为它用了分布式条件类型:当条件类型的左侧是裸的类型参数(没有被包裹在数组、对象等类型里),且参数是联合类型时,TypeScript会自动对联合类型的每个成员单独执行条件判断,再把结果合并成新的联合类型。比如KeysNoGet<keyof MyInterface>会逐个检查每个键是否以Get开头,最后合并符合要求的结果。

正确实现方式

要实现基于返回值筛选联合键的需求,有两种简洁的实现方式:

方式一:改造为分布式条件类型

让类型参数K以裸参数形式参与条件判断,触发分布式行为:

type KeysReturnStrings<K extends keyof MyInterface> = 
  K extends keyof MyInterface 
    ? ReturnType<MyInterface[K]> extends string 
      ? K 
      : never 
    : never;

type Test3 = KeysReturnStrings<keyof MyInterface>; // "GetChocolate" | "SetVanilla"

方式二:映射类型(更直观)

先通过映射类型遍历所有键,标记符合条件的键,再提取有效结果:

type KeysReturnStrings = {
  [K in keyof MyInterface]: ReturnType<MyInterface[K]> extends string ? K : never;
}[keyof MyInterface];

type Test3 = KeysReturnStrings; // "GetChocolate" | "SetVanilla"

这种方式会先为每个键生成对应的类型(符合条件保留键名,不符合则为never),最后通过[keyof MyInterface]索引访问,自动过滤掉never成员并合并成联合类型。

验证效果

两种方式都能满足需求:

  • 传入联合类型时,正确返回"GetChocolate" | "SetVanilla"
  • 传入单个键时依然正常工作:
type Test1 = KeysReturnStrings<"GetChocolate">; // "GetChocolate"
type Test2 = KeysReturnStrings<"SetChocolate">; // never

内容的提问来源于stack exchange,提问作者Prof.Chewbacca

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.17 02:18:18