如何在TypeScript类中实现兼具函数调用、子方法挂载能力的compute属性
实现方案
核心原理:JavaScript 中的函数本身就是特殊对象,可直接在函数实例上挂载自定义属性,同时保留函数的可调用特性,配合 TypeScript 类型定义即可实现需求。
具体实现步骤:
- 先定义复合类型约束,明确
compute既符合函数调用签名,又包含对应的子方法结构 - 在类构造函数中完成
compute的初始化:先创建主逻辑函数,再给函数挂载子方法,全程使用箭头函数绑定当前实例的this,确保可以访问实例私有属性specialData
完整可运行代码:
// 收窄算法类型比泛string更安全,可避免传入无效算法名的类型错误 type Algorithm = 'algorithm1' | 'algorithm2'; // 补全示例依赖的工具函数 function add(data: number[], specialData: number[]): number[] { return data.map((val, idx) => val + (specialData[idx] ?? 0)); } function multiply(data: number[], specialData: number[]): number[] { return data.map((val, idx) => val * (specialData[idx] ?? 0)); } // 定义compute的复合类型:既是可调用函数,又挂载了子方法 type Compute = { (data: number[], algorithm: Algorithm): number[]; algorithm1: (data: number[]) => number[]; algorithm2: (data: number[]) => number[]; } class Computer { public compute: Compute; constructor(private specialData: number[]) { // 1. 初始化compute主函数逻辑 this.compute = ((data: number[], algorithm: Algorithm) => { switch(algorithm) { case 'algorithm1': return this.compute.algorithm1(data); case 'algorithm2': return this.compute.algorithm2(data); default: throw new Error('Unknown algorithm'); } }) as Compute; // 2. 给compute函数挂载子方法,箭头函数自动绑定当前实例this,可正常访问specialData this.compute.algorithm1 = (data: number[]) => { return add(data, this.specialData); }; this.compute.algorithm2 = (data: number[]) => { return multiply(data, this.specialData); }; } }
验证调用效果:
const c = new Computer([1, 2, 3, 4]); const data = [2, 8, 7, 5]; // 两种调用方式都可正常运行 console.log(c.compute(data, 'algorithm1')); // 输出 [3, 10, 10, 9] console.log(c.compute.algorithm1(data)); // 输出同上 console.log(c.compute(data, 'algorithm2')); // 输出 [2, 16, 21, 20] console.log(c.compute.algorithm2(data)); // 输出同上
如果后续需要扩展更多算法,也可以把switch逻辑替换为对象映射,维护性会更高。
内容的提问来源于stack exchange,提问作者Orion
相关产品推荐
相关产品推荐

