如何用函数/装饰器处理TypeScript类并生成移除首参的新类?
如何实现移除类所有方法第一个参数的TypeScript工具?
当然可以!我们可以通过TypeScript工具类型处理类型层面的接口生成,同时配合运行时函数实现类方法的转换。下面分两部分详细说明:
1. 类型层面:生成移除第一个参数的接口
首先定义一个工具类型,用来移除单个函数的第一个参数:
// 移除函数的第一个参数 type OmitFirstParameter<T> = T extends (first: any, ...rest: infer RestArgs) => infer ReturnType ? (...rest: RestArgs) => ReturnType : T;
接着,我们可以用这个工具类型遍历类的所有方法,生成新的类型:
// 转换整个类的所有方法,移除每个方法的第一个参数 type ClassWithoutFirstParam<T> = { [MethodName in keyof T]: OmitFirstParameter<T[MethodName]>; };
现在你就可以用这个类型来定义接口C了:
// 原类定义 class A { public aCall(a: any, payload: string): void {} public bCall(a: any, payload: number): void {} public cCall(a: any): void {} } // 生成移除第一个参数的接口 interface C extends ClassWithoutFirstParam<A> {} // 此时C的类型等价于: // interface C { // aCall(payload: string): void; // bCall(payload: number): void; // cCall(): void; // }
2. 运行时层面:生成移除第一个参数的新类
接下来实现createNewClass函数,动态生成新类,让新类的方法自动调用原类实例的方法并省略第一个参数。这里假设原方法的第一个参数需要传入原实例本身(你可以根据实际需求调整第一个参数的传入值):
function createNewClass<T extends object>(originalInstance: T) { return class { constructor() { // 遍历原类原型上的所有方法 const prototype = Object.getPrototypeOf(originalInstance); Object.getOwnPropertyNames(prototype).forEach(methodName => { // 跳过构造函数,只处理方法 if (methodName === 'constructor') return; const originalMethod = originalInstance[methodName]; if (typeof originalMethod === 'function') { // 为新类绑定方法:调用原方法时,第一个参数传入原实例,后续参数由新方法接收 (this as any)[methodName] = (...args: any[]) => { return originalMethod.call(originalInstance, originalInstance, ...args); // 如果原方法的第一个参数不需要传入原实例,替换成你需要的固定值即可,比如: // return originalMethod.call(originalInstance, undefined, ...args); }; } }); } } as ClassWithoutFirstParam<T>; }
使用示例:
// 创建原类实例 const instanceA = new A(); // 生成新类 const ClassB = createNewClass(instanceA); const instanceB = new ClassB(); // 调用新方法,无需传入第一个参数 instanceB.aCall("test payload"); // 等价于 instanceA.aCall(instanceA, "test payload") instanceB.bCall(123); // 等价于 instanceA.bCall(instanceA, 123) instanceB.cCall(); // 等价于 instanceA.cCall(instanceA)
补充说明
- 如果原类的方法是静态方法,需要调整遍历逻辑(遍历原类本身而不是原型)。
- 工具类型
ClassWithoutFirstParam会自动处理所有方法,包括可选参数、重载方法等TypeScript支持的函数类型。
内容的提问来源于stack exchange,提问作者Ken
相关产品推荐
相关产品推荐

