如何通过方法名调用类实例方法并传递参数?(TypeScript)
问题分析与解决方案
你的call函数出错有两个核心问题:
- 调用API方法时参数传递错误:
Parameters<Api[Method]>返回的是方法参数组成的元组类型,比如method1的参数元组是[Method1Params]。你直接把args(数组)传给方法,相当于把整个数组作为第一个参数传递,而方法实际需要的是元组里的单个参数。 - TypeScript对泛型方法的类型推断存在小盲区,需要明确参数展开的类型兼容性。
修正后的代码如下:
type Method2Params = { a: number, b: number } type Method1Params = { a: number } class Api { method1({ a }: Method1Params): boolean { // 改用小写原始类型,大写Boolean是包装对象,日常开发不用 return a % 2 === 0 } method2({ a, b }: Method2Params): number { // 同理改用小写number return a + b } } const api = new Api(); function call<Method extends keyof Api>( method: Method, ...args: Parameters<Api[Method]> ): ReturnType<Api[Method]> { // 用展开运算符把参数元组拆解成方法需要的单个参数 const result = api[method](...args) as ReturnType<Api[Method]>; return result; } const sign = call('method1', { a: 12 }); // 正常工作,类型为boolean const sum = call('method2', { a: 5, b: 3 }); // 正常工作,类型为number
补充说明:
- 把返回类型的
Boolean/Number改成小写的boolean/number,这是TypeScript中的原始类型,大写的是对应的包装对象类型,日常开发几乎不会用到。 - 加上
as ReturnType<Api[Method]>类型断言是因为TypeScript暂时无法完美推断api[method](...args)的返回类型和泛型返回值的完全匹配,这个断言是安全的,因为我们已经确保了参数和方法的对应关系。 - 展开运算符
...args会把参数元组正确拆解成方法需要的单个参数,解决了参数不匹配的核心错误。
内容的提问来源于stack exchange,提问作者Mike Glyancev
相关产品推荐
相关产品推荐

