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

TypeScript 2.8:如何从一个对象类型中移除另一个的属性?

实现ObjectDiff<T, U>移除对象中存在于U的属性

这问题问得太实用了!刚好我之前做项目时也遇到过类似需求,咱们用TypeScript的类型工具就能轻松搞定,给你两种实现方式:

方式一:用Pick + Exclude组合(兼容性更好)

其实TypeScript已经内置了Pick和Exclude这两个工具类型,把它们组合起来就能直接实现你的需求,代码简洁还兼容更早的TS版本:

type ObjectDiff<T, U> = Pick<T, Exclude<keyof T, keyof U>>;

原理拆解:

  • Exclude<keyof T, keyof U>:先筛选出所有属于T但不在U里的属性键。拿你的例子来说,keyof A是"one" | "two" | "three",keyof Stuff是"three",所以这一步会得到"one" | "two"。
  • Pick<T, ...>:从原类型T里挑出前面得到的这些属性键,最终就得到了去掉U中存在属性的新类型。

测试你的例子:

type A = { one: string; two: number; three: Date; };
type Stuff = { three: Date; };
type AWithoutStuff = ObjectDiff<A, Stuff>;
// 实际类型:{ one: string; two: number; }

完全符合你的预期!

方式二:用映射类型键重映射(TS 4.1+)

如果你用的是TypeScript 4.1及以上版本,还可以用键重映射的方式来写,逻辑和你提到的联合类型Diff更相似,更直观:

type ObjectDiff<T, U> = {
  [K in keyof T as K extends keyof U ? never : K]: T[K];
};

原理拆解:

  • 遍历T的每个属性键K,通过as子句做条件判断:如果K是U的属性键,就把这个键替换成never(相当于排除该属性);否则保留原键K。
  • 最终只保留那些不在U中的属性,值类型和T中对应属性完全一致。

补充说明

  • 这两种方式都只判断属性键是否存在,不管属性值类型是否匹配。比如就算Stuff里的three是string而不是Date,依然会移除A中的three属性。
  • 如果需要同时判断键和值类型都匹配才移除,可以调整条件,但你的需求里只需要根据键来移除,上面的实现完全够用。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:04:44