如何使用TypeScript泛型基于类型过滤对象键并推导返回值类型
解决方案
完整实现代码
class Value<T> { val: T; constructor(val: T){ this.val = val; } get(): T { return this.val; } } let data = { foo: new Value(123), bar: new Value('abc'), baz: 'xyz' } // 定义返回值映射类型 type FilteredValue<T extends object> = { [K in keyof T as T[K] extends Value<infer V> ? K : never]: T[K] extends Value<infer V> ? V : never } // 泛型改造filter函数 let filter = <T extends object>(obj: T): FilteredValue<T> => { let result = {} as FilteredValue<T>; for (const [key, val] of Object.entries(obj)) { if(val instanceof Value) { result[key as keyof FilteredValue<T>] = val.get() as any; } } return result; }; // 类型验证 filter(data).foo; // 推导类型为number,运行时值为123 filter(data).bar; // 推导类型为string,运行时值为'abc' filter(data).baz; // TS编译阶段直接报错:属性“baz”不存在于返回类型上
逻辑说明
- 工具类型
FilteredValue<T>通过键重映射能力实现类型过滤:
- 遍历输入对象的所有键,对每个键对应的值做类型判断
- 如果值是
Value<infer V>类型就保留该键,同时用infer关键字提取Value内部包裹的泛型类型作为该键的最终类型 - 非Value类型的键会被直接过滤,不会出现在返回类型中
- filter函数绑定泛型输入和返回值映射关系后,即可实现完全的自动类型推导,无需手动标注返回结构。
内容的提问来源于stack exchange,提问作者Craig
相关产品推荐
相关产品推荐

