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

如何移除TypeScript联合类型未列出的对象属性?

TypeScript中如何根据联合类型过滤对象属性,保留指定字段?

我原本以为这在TypeScript中无法实现,但或许有误,故提出如下问题:

假设有一个对象示例:

const person = {
  name: "Feter Pox",
  city: "Berlin",
  age: "30",
};

该对象为普通对象,可按需修改,只要能正常访问name等属性即可。

同时存在一个不可修改的联合类型:

type keys = 'name' | 'age';

注意:无法将数组['name', 'age']转换为该keys类型来解决问题,因为不存在这样的数组。

需求:创建person的副本reducedPerson,仅保留keys中列出的属性,未列出的属性需完全移除。

预期结果:

const reducedPerson = {
  name: "Feter Pox",
  age: "30",
};

我尝试的方法无效:

const person = {
  name: "Feter Pox",
  city: "Berlin",
  age: "30",
};

type keys = 'name' | 'age';

const reducedPerson: Record<keys, string> = person;

reducedPerson. // 优点:自动补全仅提示'name'和'age',无'city'
console.log(reducedPerson); // 缺点:对象中仍存在'city'属性

可行解决方案

方案一:手动提取属性(适合字段较少的场景)

直接手动复制需要保留的属性,同时用Pick类型约束结果的类型,既能保证类型安全,又能彻底移除多余属性:

const person = {
  name: "Feter Pox",
  city: "Berlin",
  age: "30",
};

type keys = 'name' | 'age';

const reducedPerson: Pick<typeof person, keys> = {
  name: person.name,
  age: person.age
};

console.log(reducedPerson); // 输出:{ name: "Feter Pox", age: "30" }

方案二:通用工具函数(适合复用场景)

写一个通用的pick函数,手动传入需要保留的字段参数,结合类型断言实现类型安全的属性过滤:

const person = {
  name: "Feter Pox",
  city: "Berlin",
  age: "30",
};

type keys = 'name' | 'age';

function pick<T, K extends keyof T>(obj: T, ...keys: K[]): Pick<T, K> {
  const result = {} as Pick<T, K>;
  keys.forEach(key => {
    result[key] = obj[key];
  });
  return result;
}

// 手动传入字段参数,同时指定类型参数确保和keys类型匹配
const reducedPerson = pick<typeof person, keys>(person, 'name', 'age');

console.log(reducedPerson); // 输出:{ name: "Feter Pox", age: "30" }

说明

因为TypeScript的类型仅存在于编译阶段,没有运行时的对应数组的话,无法自动从keys类型生成需要保留的字段列表,必须手动指定要保留的字段。但通过上述方法,可以同时保证类型校验正确和实际对象无多余属性的需求。

内容的提问来源于stack exchange,提问作者Page not found

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.27 04:45:04