TypeScript中的数据选择艺术:pick和omit操作入门

引言
  • 标题:TypeScript中的数据选择艺术:pick和omit操作入门
  • 简短介绍 :探索TypeScript中的实用工具类型Pick和Omit,它们可以帮助你从现有类型中选择或排除属性,简化你的代码并提高类型安全性。
背景知识
  • 易于理解的解释 :在JavaScript和TypeScript中,经常需要从对象中提取或忽略某些属性。Pick和Omit是TypeScript提供的工具类型,用于实现这一目的。
核心概念
  • Pick:从现有类型中挑选出特定的属性,创建一个只包含这些属性的新类型。
  • Omit:从现有类型中排除指定的属性,创建一个不包含这些属性的新类型。
简单示例
  • Pick 示例:
typescript 复制代码
interface Person {
  name: string;
  age: number;
  email: string;
}

type PersonName = Pick<Person, 'name'>; // 创建一个只包含name属性的类型

const getNames = (person: PersonName) => {
  return person.name;
};
  • Omit 示例:
typescript 复制代码
interface Person {
  name: string;
  age: number;
  email: string;
}

type PersonWithoutAge = Omit<Person, 'age'>; // 创建一个不包含age属性的类型

const getPersonDetails = ({ name, email }: PersonWithoutAge) => {
  return `${name}, ${email}`;
};
深入理解
  • 工作原理 :Pick和Omit通过泛型接受两个参数:一个类型和一个属性键的联合,然后分别返回包含或排除这些属性键的新类型。
实际应用
  • 案例研究 :在一个用户信息管理系统中,使用Pick来创建一个只包含必要信息的类型,以及使用Omit来创建一个不含敏感信息的类型。
实际用例:用户信息处理
1. 基础的Pick和Omit使用

场景:假设我们有一个用户信息对象,我们只想要提取出用户的姓名和邮箱。

  • 使用Pick:
typescript 复制代码
interface User {
  name: string;
  age: number;
  email: string;
}

// 使用Pick来创建一个只包含name和email的类型
type UserBasicInfo = Pick<User, 'name' | 'email'>;

const printUserBasicInfo = ({ name, email }: UserBasicInfo): void => {
  console.log(`Name: ${name}, Email: ${email}`);
};

const user: User = {
  name: "John Doe",
  age: 30,
  email: "john.doe@example.com"
};

printUserBasicInfo(user); // 正确调用,因为user包含所需的name和email属性
  • 使用Omit:
typescript 复制代码
// 使用Omit来创建一个排除age属性的用户信息类型
type UserWithoutAge = Omit<User, 'age'>;

const printUserWithoutAge = ({ name, email }: UserWithoutAge) => {
  console.log(`Name: ${name}, Email: ${email}`);
};

printUserWithoutAge(user); // 正确调用,因为已经排除了age属性
2. 条件渲染中的Pick和Omit

场景:在一个用户界面中,根据用户的角色,我们可能需要渲染不同的信息。

  • 使用Pick:
typescript 复制代码
interface User {
  name: string;
  age: number;
  email: string;
  role: string;
}

// 管理员需要查看所有信息
type AdminUserDetails = Pick<User, 'name' | 'age' | 'email'>;

// 普通用户只能查看名字和邮箱
type RegularUserDetails = Pick<User, 'name' | 'email'>;

const renderUserDetails = (user: User, isUserAdmin: boolean) => {
  if (isUserAdmin) {
    // 管理员可以查看所有信息
    const adminDetails: AdminUserDetails = {
      name: user.name,
      age: user.age,
      email: user.email
    };
    console.log(adminDetails);
  } else {
    // 普通用户只能查看部分信息
    const regularDetails: RegularUserDetails = {
      name: user.name,
      email: user.email
    };
    console.log(regularDetails);
  }
};
3. 接口的扩展和重构

场景:随着时间推移,我们可能需要对用户信息进行扩展或重构。

  • 使用Pick和Omit进行重构:
typescript 复制代码
interface UserV1 {
  name: string;
  age: number;
  email: string;
  address: string;
}

// 假设我们需要创建一个新的接口UserV2,它不包含address属性
interface UserV2 extends Omit<UserV1, 'address'> {
  phone: string;
}

const migrateUserV1toV2 = (userV1: UserV1): UserV2 => {
  return {
    ...userV1,
    phone: "123-456-7890" // 假设这是新添加的电话号码
  };
};
4. 高级用例:函数重构和类型保护

场景:在大型应用程序中,我们可能需要重构函数以接受更少的参数,同时保持类型安全。

  • 使用Pick进行函数重构:
typescript 复制代码
function sendWelcomeEmail(user: User) {
  // 发送欢迎邮件的逻辑
}

// 假设我们只需要名字和邮箱来发送邮件
type SendWelcomeEmailParams = Pick<User, 'name' | 'email'>;

// 重构函数以使用新的参数类型
function sendWelcomeEmailRefactored(user: SendWelcomeEmailParams) {
  sendWelcomeEmail(user as User); // 由于SendWelcomeEmailParams是User的子集,这是安全的
}

const user: User = {
  name: "Jane Doe",
  age: 25,
  email: "jane.doe@example.com",
  address: "123 Main St"
};

sendWelcomeEmailRefactored(user); // 现在只需要提供name和email
常见问题
  • FAQs :
    • Q: 除了属性名,我可以传递复杂表达式给Pick和Omit吗?
      A: 不可以,这些操作符只接受属性键的直接列表作为泛型参数。
    • Q: Pick和Omit会影响原有类型吗?
      A: 不会,它们只会基于原有类型创建新类型,原有类型保持不变。
学习资源
  • 推荐阅读 :TypeScript官方文档中关于Pick和Omit的部分。
互动环节
  • 提问 :你如何在项目中使用Pick和Omit?请在评论区分享你的经验。
结语
  • 总结 :通过今天的学习,我们了解了如何使用Pick和Omit来创建更精确的类型,从而提高代码的可读性和可维护性。
相关推荐
hasty13 小时前
不上传新包,也能改变用户拿到的版本:npm dist-tag 的 OIDC 权限治理
前端·npm·node.js
zhousenshan1 天前
TypeScript 入门到精通
typescript
福兮说1 天前
前后端算的 MD5、SHA-256 对不上?编码、换行、BOM、HMAC、JSON 顺序,八个原因逐个实测
前端·javascript·node.js·json·哈希算法
花旗蜕变1 天前
前端转 NestJS 全栈实践:从表单页面到微信业务系统
前端·typescript·nestjs
lingchen19061 天前
Node.js的下载安装配置
node.js
艺杯羹1 天前
Anthropic突袭发布Claude Code Mods!用TypeScript编写智能体中间件:告别AI误删与失控
人工智能·typescript·系统架构
LRL_2 天前
【实战指南】Node.js 跨平台依赖下载:如何在 Windows/Linux 环境下互跨下载目标系统的 npm/pnpm 包
linux·windows·node.js
福兮说2 天前
URL 编码的七个坑:c++ 传到后端变空格、%25 套娃、截断 emoji 直接报错
开发语言·前端·javascript·node.js·url
liangshanbo12152 天前
Webpack vs Vite 底层原理高频追问的问题
前端·webpack·node.js
玖石书2 天前
HiSH 通过 apk 安装 Node.js、npm 与 pnpm
npm·node.js·鸿蒙·hish