如何在TypeScript中类型安全地自动转发类实例方法至另一对象?
类型安全的类方法自动转发方案
要实现无需手动编写每个转发方法,同时保证TypeScript类型安全的效果,可以通过以下两种方式解决:
方法一:动态挂载原型方法 + 接口类型声明
通过TypeScript接口让Bar的实例类型继承Foo的所有方法签名,再在构造函数中动态遍历Foo的原型方法,为Bar实例添加转发逻辑:
class Foo { greet() { return "hello"; } sayGoodbye() { return "bye"; } // 更多方法... } // 让TypeScript识别Bar实例拥有Foo的所有方法 interface Bar extends Foo {} class Bar { foo: Foo; constructor() { // 可传入自定义参数实例化Foo,解决mixin的继承反转问题 this.foo = new Foo(); // 遍历Foo原型方法,动态挂载转发函数 Object.getOwnPropertyNames(Foo.prototype) .filter(key => key !== 'constructor') .forEach(key => { const method = key as keyof Foo; (this as any)[method] = (...args: Parameters<Foo[typeof method]>) => { return this.foo[method](...args); }; }); } } // 测试:类型提示正常,调用安全 const bar = new Bar(); console.log(bar.greet()); // 输出"hello" console.log(bar.sayGoodbye()); // 输出"bye"
特点
- 类型完全安全:编辑器会自动提示
Foo的所有方法,编译时会检查参数和返回值 - 灵活控制
Foo实例化:可在Bar构造函数中传入任意参数创建Foo实例 - 方法直接挂载在实例上,性能优于Proxy方案
方法二:Proxy代理拦截 + 类型断言
使用Proxy拦截Bar实例的属性访问,自动将方法调用转发给foo实例,同时通过类型断言让TypeScript识别Bar拥有Foo的方法:
class Foo { greet() { return "hello"; } sayGoodbye() { return "bye"; } } class Bar { foo: Foo; constructor() { this.foo = new Foo(); // 返回Proxy实例,拦截方法调用 return new Proxy(this, { get(target, prop) { // 判断是否为Foo的方法 if (typeof target.foo[prop as keyof Foo] === 'function') { return (...args: any[]) => target.foo[prop as keyof Foo](...args); } // 非方法属性直接返回自身值 return Reflect.get(target, prop); } }) as Bar & Foo; } } // 测试类型安全 const bar = new Bar(); bar.greet(); // 自动提示方法,类型检查有效
特点
- 无需手动遍历方法,
Foo新增方法会自动被转发 - 代码更简洁,逻辑集中在Proxy拦截器中
- 需注意Proxy的兼容性(现代浏览器/Node.js均支持)
内容的提问来源于stack exchange,提问作者Adam B.
相关产品推荐
相关产品推荐

