TypeScript如何实现按属性值类型筛选泛型类型的属性
实现方法
完全可以通过TypeScript原生的类型工具组合实现按属性值类型筛选,不需要额外依赖。核心思路是先筛选出所有值类型匹配目标类型的键,再通过Pick提取对应属性。
可直接复用的实现
class Test { value1!: Date value2!: number value3!: Date value4!: string } type FilterProperties<T, TFieldType> = Pick< T, { [K in keyof T]: T[K] extends TFieldType ? K : never }[keyof T] > // 验证效果 const onlyDates = {} as FilterProperties<Test, Date> // 推导得到onlyDates类型为 { value1: Date; value3: Date },完全符合预期
原理拆解
- 内层的映射类型会遍历
T的所有属性键K,判断当前属性值T[K]是否匹配目标类型TFieldType:匹配则返回键名K,不匹配则返回never - 用
[keyof T]做索引访问时,never会在联合类型中被自动排除,最终得到所有符合值类型要求的键名联合 - 最后通过内置的
Pick工具类型,从原类型T中取出这些键对应的属性,就是最终要的筛选结果
严格匹配版本(可选)
上面的实现是子类型兼容的(比如Date的子类实例也会被筛选出来),如果需要属性值和目标类型完全相等,可以把判断条件换成双向extends校验:
type StrictFilterProperties<T, TFieldType> = Pick< T, { [K in keyof T]: [TFieldType, T[K]] extends [T[K], TFieldType] ? K : never }[keyof T] >
你之前尝试Extract和Pick没有成功,是因为这两个工具默认都是针对键名做处理,缺少了「根据值类型反向筛选键名」的中间步骤,自然无法实现按值类型过滤的效果。
内容的提问来源于stack exchange,提问作者Peter
相关产品推荐
相关产品推荐

