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

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>>;

实现逻辑说明

  1. 先通过映射类型遍历泛型T的所有属性,对每个属性做条件判断:如果属性值是函数类型则保留该属性名,否则返回never
  2. 通过索引访问[keyof T]提取所有非never的属性名,得到所有方法的key联合
  3. 借助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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.27 05:39:00