TypeScript中如何实现仅提取目标类型存在的指定属性子集?
解决方案
要实现只提取目标类型中实际存在的预定义属性子集,你需要先筛选出预定义Keys与目标类型Key的交集,再进行Pick操作。之前的实现错误在于直接对所有预定义Keys执行Pick,而没有过滤掉目标类型不存在的属性。
正确类型定义
interface Properties { name: string; animal: boolean; plant: boolean; fly: boolean; swim: boolean; walk: boolean; } type Bird = Pick<Properties, 'name' | 'animal' | 'fly'>; // 正确实现:先筛选出T中存在的预定义Keys,再Pick type SubsetPick<T, K extends keyof any> = Pick<T, Extract<keyof T, K>>; // 针对你的场景,可以固定预定义Keys(也可以保留泛型参数让其更通用) type MovementSubset<T> = SubsetPick<T, 'fly' | 'swim' | 'walk'>; // 测试:现在swim和walk会报错,因为Bird中不存在这两个属性 const birdSubset: MovementSubset<Bird> = { fly: true, swim: true, // ❌ 错误:类型“{ fly: true; swim: true; walk: true; }”中属性“swim”与类型“MovementSubset<Bird>”不兼容 walk: true // ❌ 错误:类型“{ fly: true; swim: true; walk: true; }”中属性“walk”与类型“MovementSubset<Bird>”不兼容 } // 合法的赋值示例 const validBirdSubset: MovementSubset<Bird> = { fly: true }
原理说明
Extract<keyof T, K>:从预定义的Keys集合K中,筛选出目标类型T实际包含的Key,得到两者的交集。Pick<T, ...>:基于筛选后的交集Key,提取T对应的属性类型,确保返回类型只包含T中存在的属性。
如果需要更通用的复用,可以直接使用SubsetPick<T, K>,传入任意目标类型和预定义Keys集合即可。
内容的提问来源于stack exchange,提问作者j3ff
相关产品推荐
相关产品推荐

