实现 TS 内置的 Pick<T, K>

文章介绍了如何在TypeScript中不依赖内置的Pick<T,K>,而是通过自定义MyPick类型推导机制,从接口如Todo中选择指定属性,构建新的类型实例。

 不使用 Pick<T, K> ,实现 TS 内置的 Pick<T, K> 的功能。

从类型 T 中选出符合 K 的属性,构造一个新的类型

例如:

interface Todo {
  title: string
  description: string
  completed: boolean
}

type TodoPreview = MyPick<Todo, 'title' | 'completed'>

const todo: TodoPreview = {
    title: 'Clean room',
    completed: false,
}

解法:

type MyPick<T, K extends keyof T> = {
    [key in K] : T[key]
    
}

03-29
<think>嗯,用户问的是TypeScript中的Pick工具类型的使用和例子。首先,我需要确认自己对Pick的理解是否正确。PickTypeScript中的一个工具类型,用于从现有类型中选择部分属性来创建新类型。它的语法是Pick<T, K>,其中T是原始类型,K是要选择的属性键的联合类型。 接下来,用户可能需要具体的例子来理解如何使用。比如,假设有一个用户信息类型User,包含id、name、email和age。如果只需要id和name,可以用Pick<User, 'id' | 'name'>来创建一个新类型。这样,新类型就只包含这两个属性。 然后,我需要考虑实际应用场景,比如API响应中可能只需要部分字段,或者表单处理时只需要某些属性。这些例子能帮助用户更好地理解Pick的实用性。 另外,用户可能想知道Pick和Omit、Partial等其他工具类型的区别。比如,Omit是排除某些属性,而Partial是将所有属性变为可选。不过用户的问题主要是关于Pick,所以可能需要简要提到这些以作对比,但重点还是放在Pick上。 还要注意用户提供的引用中提到了Partial,引用[1]说Partial让所有属性变为可选。虽然用户的问题是关于Pick的,但可能需要确认是否需要将Pick与Partial结合使用的情况,比如Pick某些属性后再加上Partial,但这可能属于更高级的用法,用户可能暂时不需要,但可以提一下作为扩展。 需要检查是否有常见的错误用法,比如属性键不存在于原始类型中,这时TypeScript会报错。例如,如果User没有address属性,Pick<User, 'address'>就会出错。这一点需要强调,帮助用户避免错误。 另外,用户提供的引用中有关于Vim插件和自然语言生成的内容,但这些可能与当前问题无关,可以忽略。只需要关注引用[1]中提到的Partial,作为相关工具类型的例子,但用户的问题是关于Pick的,所以主要回答Pick,可能在对比时提到Partial。 可能还需要提供代码示例,确保语法正确。比如定义User类型,然后用Pick创建BasicUser,并展示如何使用。代码中的类型是否正确,比如字符串、数字等是否匹配,是否需要可选属性等。 用户可能还想知道Pick在函数参数或React组件props中的应用,比如提取部分props来创建子组件需要的类型。这也是一个实际的应用场景,可以举例说明。 总结回答的结构:先介绍Pick的作用,语法,然后给出示例,再讨论应用场景,与其他工具类型的对比,常见错误,最后总结。这样结构清晰,便于用户逐步理解。 需要确认所有的TypeScript语法是否正确,比如使用interface还是type,联合类型的写法是否正确,比如用单引号还是双引号,不过TypeScript中两者都可以,但保持示例一致。 可能还需要提到Pick内置TypeScript中的,不需要额外安装,属于实用工具类型的一部分,帮助用户了解其来源。 最后,生成相关问题,比如Pick和Omit的区别,Pick与Partial的结合使用,或者如何处理动态选择属性的情况。这些相关问题可以帮助用户进一步深入学习。</think>### TypeScriptPick 工具类型详解 #### 1. 基本概念 `Pick` 是 TypeScript 提供的**实用工具类型**,用于从现有类型中**选择指定属性**生成新类型。其语法为: $$Pick<T, K>$$ 其中: - `T`:原始类型 - `K`:需要保留的属性键(字符串字面量类型或联合类型) #### 2. 使用示例 **场景**:用户信息类型需要提取基础字段 ```typescript interface User { id: number; name: string; email: string; age: number; } // 选择 id 和 name 属性 type BasicUser = Pick<User, 'id' | 'name'>; // 合法使用 const user: BasicUser = { id: 1, name: "Alice" }; // 错误示例(缺少 name) const invalidUser: BasicUser = { id: 2 }; // 报错: Property 'name' is missing ``` #### 3. 核心特性 1. **精确属性筛选** 只保留明确指定的属性,未选择的属性会自动排除 2. **类型安全校验** 若指定不存在的属性会触发编译错误: ```typescript type Invalid = Pick<User, 'address'>; // 报错:'address' does not exist in type 'User' ``` 3. **与 `Partial` 组合使用** 可将选择的属性设为可选(引用[1]中提到的`Partial`类型): ```typescript type OptionalBasicUser = Partial<Pick<User, 'email' | 'age'>>; ``` #### 4. 应用场景 | 场景 | 示例 | |---------------------|-------------------------------| | API 响应数据过滤 | 提取接口返回的必要字段 | | 表单数据处理 | 创建仅含表单字段的类型 | | 组件 Props 类型约束 | 复用已有类型的部分属性(React/Vue) | #### 5. 相关工具类型对比 | 工具类型 | 行为 | 示例 | |-------------|-----------------------|-------------------------------| | `Pick<T,K>` | 保留指定属性 | `Pick<User, 'id'>` | | `Omit<T,K>` | 排除指定属性 | `Omit<User, 'password'>` | | `Partial<T>`| 所有属性设为可选 | `Partial<User>`(引用[1]) |
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值