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

对象联合类型:如何筛选指定键?

问题描述

我定义了如下对象联合类型:

type Runner = |
    {company: "Apple", name: "tests", payload: number} |
    {company: "Apple", name: "cleanup", payload: string} |
    {company: "Google", name: "tests", payload: number};

我需要定义一个函数,接收该联合类型但只保留指定键(此处为company和name),同时必须保留原联合类型的约束:

  • 当company为"Apple"时,name可以是"tests"或"cleanup"
  • 当company为"Google"时,name只能是"tests"

直接使用Pick<Runner, "company" | "name">会丢失联合约束,它会生成一个包含所有可能值的交叉类型,而不是保留原有的联合成员结构。我需要一个类似PickKeys<Runner, "company" | "name">的类型,让它等价于以下函数参数的类型:

function run(
    runner: |
        {company: "Apple", name: "tests"} |
        {company: "Apple", name: "cleanup"} |
        {company: "Google", name: "tests"}
) {}
解决方案

可以利用TypeScript的分布式条件类型特性,定义一个对联合类型中每个成员单独执行Pick操作的工具类型:

type PickKeys<T, K extends keyof T> = T extends unknown ? Pick<T, K> : never;

然后就可以用这个类型来实现需求:

type RunnerPick = PickKeys<Runner, "company" | "name">;

// 验证一下,这个类型等价于我们需要的联合类型
function run(runner: RunnerPick) {}

// 符合约束的参数可以正常通过
run({ company: "Apple", name: "tests" });
run({ company: "Apple", name: "cleanup" });
run({ company: "Google", name: "tests" });

// 不符合约束的参数会触发类型错误
run({ company: "Google", name: "cleanup" }); // 类型错误,符合预期

原理说明

当T是联合类型时,T extends unknown ? Pick<T, K> : never会自动将联合类型拆分成单个成员,对每个成员单独应用Pick<T, K>,最后再把结果重新组合成联合类型。这种分布式条件类型的特性,专门用来处理联合类型的逐个成员操作,完美解决了直接使用Pick丢失联合约束的问题。

内容的提问来源于stack exchange,提问作者Myzel394

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 21:45:55