You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

TypeScript 如何实现可提取多个嵌套属性子键的PickMultiple工具类型

实现代码

首先需要先实现一个通用的联合转交叉工具类型,再基于它实现PickMultiple:

// 通用工具类型:将联合类型转换为交叉类型
type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never

// 目标PickMultiple实现
type PickMultiple<T, KArr extends Array<keyof T>> = UnionToIntersection<T[KArr[number]]>

实现逻辑说明

  • 泛型约束KArr extends Array<keyof T>:保证传入的数组元素只能是目标接口的顶级键,避免传入非法键
  • KArr[number]:将数组类型转换为数组元素组成的联合类型,比如['a','b']会被转换为'a' | 'b'
  • T[KArr[number]]:拿到所有选中顶级键对应的子对象的联合类型,示例中得到{name: string} | {age: number}
  • UnionToIntersection:将联合类型转换为交叉类型,示例中最终得到{name: string} & {age: number},也就是符合要求的平层类型

效果验证

代入你提供的示例代码测试完全符合预期:

interface A{
  a:{
    name: string
  }
  b:{
    age: number
  }
}

const child: PickMultiple<A, ['a','b']> = {
   name: 'mike',
   age: 18
}
// 类型校验正常通过,无报错

可选简化写法(无同名属性场景可用)

如果你的使用场景里不存在多个子对象有同名属性的情况,可以不用额外引入UnionToIntersection,用映射类型直接实现:

type PickMultiple<T, KArr extends Array<keyof T>> = {
  [K in keyof T[KArr[number]]]: T[KArr[number]][K]
}

两种实现的差异在于:如果出现同名属性,交叉类型版本会取属性类型的交集,映射类型版本会取属性类型的联合,可根据实际需求选择。

内容的提问来源于stack exchange,提问作者xipper

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.07 15:15:01