TypeScript如何创建按值类型过滤类/接口属性、仅提取方法的类型?
正确实现提取类中方法属性的TypeScript泛型
完整实现代码
// 通用函数类型匹配规则 type AnyFunction = (...args: any[]) => any; // 提取类型中所有值为函数的属性名联合 type MethodKeys<T extends object> = { [K in keyof T]: T[K] extends AnyFunction ? K : never }[keyof T]; // 最终泛型:仅保留类型中的方法属性 type MethodsOf<T extends object> = Pick<T, MethodKeys<T>>;
实现逻辑说明
- 先通过映射类型遍历泛型T的所有属性,对每个属性做条件判断:如果属性值是函数类型则保留该属性名,否则返回
never - 通过索引访问
[keyof T]提取所有非never的属性名,得到所有方法的key联合 - 借助TS内置的
Pick工具类型,从原类型中筛选出方法key对应的属性,得到仅包含方法的目标类型
效果验证
拿你给出的Person类测试,完全符合需求:
class Person { name = "Ann"; sleep() { /*...*/ } eat() { /*...*/ } } // ✅ 正常通过类型校验 const personMethods: MethodsOf<Person> = { sleep() {}, eat() {} }; const names: (keyof MethodsOf<Person>)[] = ['sleep', 'eat']; // ❌ 触发类型错误,符合预期 // 报错:对象字面量只能指定已知属性,"notAPersonMethod" 不在类型 "MethodsOf<Person>" 中 const personMethods2: MethodsOf<Person> = { notAPersonMethod() {} }; // 报错:类型 "not" 不能分配给类型 "sleep" | "eat" const names2: (keyof MethodsOf<Person>)[] = ['not', 'existing', 'methods']; // 报错:不能将类型 "{ name: string; }" 分配给类型 "Partial<MethodsOf<Person>>" const test2: Partial<MethodsOf<Person>> = { name: 'Ann' };
原有代码的问题
你之前的实现多定义了不必要的Key泛型参数,且没有正确完成条件过滤逻辑,导致所有属性key都被保留,因此非方法属性name也能通过校验。
内容的提问来源于stack exchange,提问作者jlang
相关产品推荐
相关产品推荐

