TypeScript父类中如何定义类型使其仅返回子类的所有函数属性
实现方案
首先定义一个工具类型,用于提取类型中所有值为函数的属性集合:
type FunctionProperties<T> = Pick<T, { [K in keyof T]: T[K] extends Function ? K : never }[keyof T]>
将父类改造为带泛型约束的抽象基类,使用奇异递归模板模式(CRTP)让父类可以获取到子类的类型定义:
abstract class Service<T extends Service<T>> { word: string = "hi" get actions(): FunctionProperties<T> { return this as unknown as FunctionProperties<T> } }
子类继承父类时,将自身作为泛型参数传入即可:
class TestService extends Service<TestService> { hello() {} greet() {} }
效果验证
const service = new TestService() // 方法可以正常调用,类型提示完整 service.actions.hello() service.actions.greet() // 非函数属性会触发类型报错,符合预期 console.log(service.actions.word) // 报错:类型“FunctionProperties<TestService>”上不存在属性“word”
原理解释
FunctionProperties工具类型通过条件类型遍历目标类型的所有属性键,过滤掉非函数类型的属性,仅保留类方法构成新类型- 父类的泛型参数约束为继承自身的子类类型,不需要在父类中硬编码方法名,新增子类方法时
actions的返回类型会自动同步 - 运行时
this本身就包含所有实例方法,所以返回this的类型断言是安全的,不会有运行时问题
内容的提问来源于stack exchange,提问作者frankw
相关产品推荐
相关产品推荐

