[Typescript] Understanding Distributive Omit and Pick in TypeScript
We start with three interface types: User
, Organisation
, and Product
.
These types share common properties: id
, name
, and imageId
, but each also possess unique fields. The User
type includes age
, Organisation
has address
, and Product
contains price
:
type User = {
id: string;
name: string;
age: number;
imageId: string;
};
type Organisation = {
id: string;
name: string;
address: string;
imageId: string;
};
type Product = {
id: string;
name: string;
price: number;
imageId: string;
};
And we want to omit `id`:
If we do as such:
type Entity = User | Organisation | Product
type EntityWithoutId = DistributiveOmit<Entity, "id">
We can see a basic object type comprising only of name
and imageId
, which are the shared properties amongst the three types.
The reason this happens is due to a technicality of how Omit processes union types.
Omit doesn't iterate over every member of the union. Instead, it mushes the union into a structure it comprehends, and then operates on this new construct. As a result, the outcome is different than what you might expect.
To remedy this, here's a DistributiveOmit
type, which has a similar type definition to Omit, but operates on every member of the union individually.
type DistributiveOmit<T, K extends PropertyKey> = T extends any
? Omit<T, K>
: never;
type DistributivePick<T, K extends PropertyKey> = T extends any
? Pick<T, K>
: never;
When applied to our EntityWithoutId
type, we now have a union of the User
, Organisation
and Product
types without the id
field—exactly as initially expected.
type EntityWithoutId = DistributiveOmit<Entity, "id">;
// Hovering over EntityWithoutId shows:
type EntityWithoutId = Omit<User, "id"> | Omit<Organisation, "id"> | Omit<Product, "id">
type test = Expect<
Equal<
EntityWithoutId,
{
name: string;
age: number;
imageId: string;
} | {
name: string;
address: string;
imageId: string;
} | {
name: string;
price: number;
imageId: string;
}
>
>;
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具
2022-07-11 [TypeScript] Variadic Tuple Types V4 ...T
2021-07-11 [SSH] SSH Troubleshooting
2021-07-11 [SAA + SAP] 02. Security
2019-07-11 [React Native] Style React Native Components Differently on iOS and Android
2019-07-11 [Debug] Dev tool Pause on caught exception
2018-07-11 [Algorithms] The Bayes Rule
2018-07-11 [Node.js] Add Logging to a Node.js Application using Winston