如何简洁地将父类静态与实例属性赋值给子类basePolicy?
问题描述
我有如下基类和子类的代码结构:
abstract class Base { // 类方法 public static findOne() {} public static findMany() {} // 实例方法 public save() {console.log('base save')} } class Child extends Base { // 类方法 public static basePolicy = ? // 实例方法 public basePolicy = ? // 重写的实例方法 public save() {console.log('child save')} } // 调用静态的basePolicy,期望执行Base.findOne() const record = await Child.basePolicy.findOne() // 调用实例的basePolicy,期望执行super.save() record.basePolicy.save();
我希望实现上述调用效果,但不想像下面这样逐个方法手动封装(过于冗长),有没有更简洁且保留类型提示的实现方式?
class Child extends Base { // 类方法 public static basePolicy = { findOne() { return super.findOne() }, findMany() { return super.findMany() } } // 实例方法 public basePolicy = { save() { return super.save() } } }
简洁实现方案
1. 静态方法代理:直接复用基类静态属性
对于静态的basePolicy,可以直接指向基类构造函数,无需手动封装每个方法,同时完整保留类型:
class Child extends Base { public static basePolicy = Base; }
调用Child.basePolicy.findOne()就等价于直接调用Base.findOne(),所有基类静态方法都能直接使用。如果只需要暴露部分静态方法,用Pick类型筛选即可:
class Child extends Base { public static basePolicy: Pick<typeof Base, 'findOne' | 'findMany'> = Base; }
2. 实例方法代理:批量绑定super上下文
对于实例的basePolicy,可以通过工具函数批量提取基类原型方法并绑定当前实例的super上下文,避免逐个写方法:
// 通用工具函数:批量生成基类方法的代理 function createBaseInstanceProxy<T extends object>( instance: T, basePrototype: object, methodNames: (keyof T)[] ) { const proxy = {} as { [K in keyof T]: T[K] }; methodNames.forEach(name => { proxy[name] = basePrototype[name].bind(instance); }); return proxy; } class Child extends Base { public basePolicy = createBaseInstanceProxy(this, Base.prototype, ['save']); }
如果基类新增实例方法,只需在数组中添加对应方法名即可,无需修改代理结构。
3. 简化版实例代理(单方法场景)
如果只有少量实例方法需要代理,也可以用更简洁的箭头函数直接绑定:
class Child extends Base { public basePolicy = { save: () => super.save() }; }
这种写法比手动写函数体更简短,同时保留类型提示。
4. 类型约束强化
如果需要严格的类型校验,可以提前定义对应的类型别名:
// 定义静态策略类型 type BaseStaticPolicy = Pick<typeof Base, 'findOne' | 'findMany'>; // 定义实例策略类型 type BaseInstancePolicy = Pick<Base, 'save'>; class Child extends Base { public static basePolicy: BaseStaticPolicy = Base; public basePolicy: BaseInstancePolicy = { save: () => super.save() }; }
这种方式让类型定义更清晰,同时确保basePolicy只能包含指定的方法。
内容的提问来源于stack exchange,提问作者Božidar Vulićević
相关产品推荐
相关产品推荐

