TypeScript 中Omit 工具类型的实用技巧

 更新时间:2026年05月13日 09:39:20   作者:哈希茶馆  
Omit是TypeScript中一个工具类型,用于从现有类型中排除特定属性,创建新类型,本文介绍了Omit的基本用法、实用技巧、与Partial、Readonly等等结合使用,感兴趣的可以了解一下

前言

在 TypeScript 开发中,我们经常需要基于现有类型创建新的类型。有时,我们希望新类型继承原类型的大部分属性,但排除掉其中一小部分。Omit<Type, Keys> 工具类型正是为此而生,它提供了一种简洁、类型安全的方式来实现这一需求。本文将带你了解 Omit 的基本用法和一些实用技巧。

什么是 Omit?

Omit<Type, Keys> 是 TypeScript 内置的一个工具类型,它的作用是构造一个新类型,该类型拥有 Type 的所有属性,但排除了 Keys 中指定的属性。这里的 Keys 通常是一个字符串字面量,或者是字符串字面量的联合类型。

基本语法

type NewType = Omit<OriginalType, 'propToExclude1' | 'propToExclude2'>;

简单示例

假设我们有一个 User 接口:

interface User {
  id: number;
  name: string;
  email: string;
  isAdmin: boolean;
  createdAt: Date;
}

如果我们想创建一个不包含 emailisAdmin 属性的 UserProfile 类型,可以这样做:

type UserProfile = Omit<User, 'email' | 'isAdmin'>;

// 此时,UserProfile 类型等同于:
// {
//   id: number;
//   name: string;
//   createdAt: Date;
// }

const userProfile: UserProfile = {
  id: 1,
  name: 'Alice',
  createdAt: new Date(),
};
// userProfile.email; // 类型错误:属性“email”在类型“UserProfile”上不存在。

Omit 的实用技巧

1. 创建用于数据提交的类型

在创建或更新实体时,某些字段(如 idcreatedAtupdatedAt 等)通常是由后端生成或管理的,前端提交数据时不需要包含它们。Omit 可以帮助我们方便地从完整的实体类型中派生出用于提交的载荷(Payload)类型。

interface Article {
  id: string;
  title: string;
  content: string;
  authorId: number;
  views: number;
  createdAt: Date;
  updatedAt: Date;
}

// 创建文章时,不需要提交 id, views, createdAt, updatedAt
type CreateArticlePayload = Omit<Article, 'id' | 'views' | 'createdAt' | 'updatedAt'>;

// CreateArticlePayload 类型为:
// {
//   title: string;
//   content: string;
//   authorId: number;
// }

function submitNewArticle(payload: CreateArticlePayload) {
  // ...提交逻辑
  console.log(payload.title);
}

submitNewArticle({
  title: 'Understanding Omit in TypeScript',
  content: 'Omit is a powerful utility type...',
  authorId: 101,
});

2. 隐藏敏感或不必要的信息

interface UserAccount {
  userId: string;
  username: string;
  email: string;
  passwordHash: string; // 敏感信息
  internalFlags: string; // 内部信息
  isActive: boolean;
}

// 定义一个公开的用户信息类型,不包含 passwordHash 和 internalFlags
type PublicUserInfo = Omit<UserAccount, 'passwordHash' | 'internalFlags'>;

// PublicUserInfo 类型为:
// {
//   userId: string;
//   username: string;
//   email: string;
//   isActive: boolean;
// }

function getUserInfoForClient(account: UserAccount): PublicUserInfo {
  // 实际实现中,你可能需要手动挑选属性或使用库
  // 但类型定义确保了返回对象的结构是正确的
  return {
    userId: account.userId,
    username: account.username,
    email: account.email,
    isActive: account.isActive,
  };
}

3. 确保属性名准确无误

Omit 的第二个参数 Keys 必须是 keyof Type 的子集。这意味着如果你尝试排除一个在原始类型中不存在的属性名,TypeScript 编译器会报错。这有助于在编译阶段就发现属性名的拼写错误。

interface Product {
  sku: string;
  name: string;
  price: number;
  description: string;
}

// 尝试 Omit 一个不存在的属性 'descripton' (拼写错误)
// type ProductSummary = Omit<Product, 'descripton' | 'sku'>;
// TypeScript 编译器会报错:
// Type '"descripton"' does not satisfy the constraint 'keyof Product'.

// 正确的写法
type ProductSummary = Omit<Product, 'description' | 'sku'>;
// ProductSummary 类型为:
// {
//   name: string;
//   price: number;
// }

4. 与其他工具类型结合

Omit 可以与其他 TypeScript 工具类型(如 Partial, Readonly)结合使用,创建更复杂的类型转换。

interface Config {
  readonly id: string;
  apiKey: string;
  timeout: number;
  debugMode: boolean;
}

// 假设我们想创建一个可修改部分配置的类型,但不允许修改 id,并且 debugMode 是可选的
// 1. 先 Omit掉 id
type ConfigWithoutId = Omit<Config, 'id'>;
// ConfigWithoutId = { apiKey: string; timeout: number; debugMode: boolean; }

// 2. 再将 debugMode 设为可选
type UpdateConfigPayload = Partial<Pick<ConfigWithoutId, 'debugMode'>> & Omit<ConfigWithoutId, 'debugMode'>;
// 或者更简洁地,如果目标是让部分属性可选,同时排除其他属性:
type ModifiableConfig = Omit<Partial<Config>, 'id'>;
// ModifiableConfig = { apiKey?: string; timeout?: number; debugMode?: boolean; }
// 注意:这种组合方式需要仔细考虑最终生成的类型结构是否符合预期。

// 一个更常见的组合:创建一个类型,其中某些属性被省略,其余属性变为可选
type OptionalEditableUser = Partial<Omit<User, 'id' | 'createdAt'>>;
// OptionalEditableUser 类型为:
// {
//   name?: string;
//   email?: string;
//   isAdmin?: boolean;
// }

Omit vs. Pick

Omit<T, K>Pick<T, K> 是 TypeScript 中一对功能相对的工具类型:

  • Pick<T, K>: 从类型 T选取 一组属性 K 来构造一个新类型。
  • Omit<T, K>: 从类型 T排除 一组属性 K 来构造一个新类型。

实际上,Omit<T, K> 在内部可以理解为 Pick<T, Exclude<keyof T, K>>

选择使用哪个取决于你的意图:

  • 当你明确知道想要 保留 哪些少数属性时,使用 Pick 更直观。
  • 当你明确知道想要 移除 哪些少数属性时,使用 Omit 更方便。

总结

Omit 是 TypeScript 工具类型库中一个非常实用且强大的成员。它通过允许我们从现有类型中排除特定属性,简化了创建新类型定义的过程,从而提高了代码的类型安全性、可读性和可维护性。熟练掌握 Omit 的使用,能让你的 TypeScript 代码更加灵活和健壮。

到此这篇关于TypeScript 中Omit 工具类型的实用技巧的文章就介绍到这了,更多相关TypeScript Omit工具类型内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • JS实现数组扁平化的8种方式总结

    JS实现数组扁平化的8种方式总结

    数组扁平化指的是将一个多层嵌套的数组,处理成只有一层的数组,本文为大家整理了8个常用的JS实现数组扁平化的方法,希望对大家有所帮助
    2023-08-08
  • JavaScript中深拷贝与浅拷贝详解

    JavaScript中深拷贝与浅拷贝详解

    大家好,本篇文章主要讲的是JavaScript中深拷贝与浅拷贝详解,感兴趣的同学赶快来看一看吧,对你有帮助的话记得收藏一下
    2022-02-02
  • js中class的点击事件没有效果的解决方法

    js中class的点击事件没有效果的解决方法

    下面小编就为大家带来一篇js中class的点击事件没有效果的解决方法。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2016-10-10
  • 微信小程序实现图片上传、删除和预览功能的方法

    微信小程序实现图片上传、删除和预览功能的方法

    这篇文章主要介绍了微信小程序实现图片上传、删除和预览功能的方法,涉及微信小程序界面布局、事件响应及图片操作相关实现技巧,需要的朋友可以参考下
    2017-12-12
  • 详细聊聊JS中不一样的深拷贝

    详细聊聊JS中不一样的深拷贝

    对于js中的对象的深拷贝在项目的开发中比较常用到,这篇文章主要给大家介绍了关于JS中不一样的深拷贝的相关资料,文中通过示例代码介绍的非常详细,需要的朋友可以参考下
    2022-10-10
  • js 提取某()特殊字符串长度的实例

    js 提取某()特殊字符串长度的实例

    下面小编就为大家分享一篇js 提取某()特殊字符串长度的实例,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2017-12-12
  • js 奇葩技巧之隐藏代码

    js 奇葩技巧之隐藏代码

    这篇文章主要介绍了js 奇葩技巧之隐藏代码,通过代码示例展示了隐藏代码的过程,需要的朋友可以参考下
    2017-08-08
  • 面向对象Javascript核心支持代码分享

    面向对象Javascript核心支持代码分享

    Javascript做面向对象开发的时候,总是会用到很多模拟面向对象特性的方法,这些方法就构成了支撑面向对象Javascript的核心代码
    2012-05-05
  • JavaScript使用encodeURI()和decodeURI()获取字符串值的方法

    JavaScript使用encodeURI()和decodeURI()获取字符串值的方法

    这篇文章主要介绍了JavaScript使用encodeURI()和decodeURI()获取字符串值的方法,实例分析了encodeURI()和decodeURI()函数解析字符串的相关技巧,需要的朋友可以参考下
    2015-08-08
  • JavaScript脚本性能优化注意事项

    JavaScript脚本性能优化注意事项

    本文总结了我在JavaScript编程中所找到的提高JavaScript运行性能的一些方法,其实这些经验都基于几条原则
    2008-11-11

最新评论