一文讲清 TypeScript 的 Omit 和 Exclude 使用方式与功能对比
背景
TypeScript 为了开发者提供了基础数据类型, 同时也允许开发者使用 interface
、type
等指令自定义复杂结构类型。与编程变量类似,开发者不能无节制的新增类型,类型的整体集中管理是降低维护成本的重要手段。
对于更多复杂的类型,开发者可以基于基础类型进行衍生,TypeScript 提供了丰富的内置的工具类型,例如本文将会介绍的**Omit
** 和 Exclude
。基于这些工具类型,我们可以将基础类型组装成任意需要的样子。
场景假设
假如我们面临需要从一个复杂的类型中排除某些属性,重写一个类型又增加了开发负担和后续维护成本。
假设我们需要一个 UserName
这样的类型,即排除掉 User
类型中的 id
、passwordHash
、address
shellinterface User { id: string; name: string; name1: string; name2: string; name3: string; name4: string; name5: string; name6: string; name7: string; passwordHash: string; address: string; }
TypeScript 中 Omit
和 Exclude
都有排除属性的能力,但是两者的使用场景和具体功能又不是完全一样,所以我们需要详细的对比两者,然后梳理出使用方式。
功能介绍
Exclude
Exclude<T, U>
的主要作用是从 T
类型中排除出可以赋值给 U
的类型,创建出一个新的子类型。比如下面的例子:
typescripttype T = 'a' | 'b' | 'c'; type U = 'a' | 'b'; type Result = Exclude<T, U>; // 结果是 'c'
说明:
在这个例子中,我们定义了两个类型 T
和 U
,T
是一个包含 'a'
, 'b'
, 'c'
三个成员的联合类型,而 U
是包含 'a'
, 'b'
的联合类型。通过 Exclude<T, U>
我们从 T
中排除了可以赋值给 U
的类型,所以结果类型 Result
就变成了 'c'
。
Omit
Omit<T, K>
的主要功能在于,从一个已有的对象类型 T
中排除指定的属性 K
,进而创建一个新的对象类型。比如下面的例子:
typescripttype T = { a: number; b: string; c: boolean; }; type K = 'a' | 'b'; type Result = Omit<T, K>; // 结果是 { c: boolean }
说明:
在这个例子中,我们定义了一个对象类型 T
,包含 'a', 'b' 和 'c' 三个属性。我们希望经过处理后得到一个新的对象类型,这个类型只包含 T
中的 'c' 属性。于是我们用 Omit<T, K>
排除了 'a' 和 'b' 两个属性,得到的新类型 Result
就只包含了 { c: boolean }
属性。
功能对比
Exclude
和 Omit
的主要区别在于它们处理类型的方式和侧重点。
Exclude
是针对联合类型,用于排除一些特定成员类型;Omit
是针对对象类型,用于忽略或排除某些特定属性;
回答场景假设
由于 User
是对象类型,并且需要排除掉排除掉 User
类型中的 id
、passwordHash
、address
,可以参考如下代码
typescriptinterface User { id: string; name: string; name1: string; name2: string; name3: string; name4: string; name5: string; name6: string; name7: string; passwordHash: string; address: string; } // 参考这个写法 type UserName = Omit<User,'id'|'passwordHash'|'address'>
总结
在实际的编程实践中,如何选择这两个工具类型取决于我们的具体需求。如果我们希望在处理对象类型时排除掉一些属性,那么 Omit
就是一个非常好的选择。而如果我们需要从一个类型联合中排除特定的类型,那么 Exclude
就派上了用场。