TypeScript动态调用类方法:类型联合兼容问题修复求助
TypeScript动态调用不同参数类方法的类型问题
需求:在TypeScript中动态调用名称不同、参数接口各异的类方法,要求避免使用any类型和if分支。当前代码在常量定义调用规则时可正常运行,但接收Input联合类型参数的函数内无法工作,存在类型联合相关问题。
原代码
// 完全不同的接口,字段各异 interface A { foo: boolean; } interface B { bar: string; baz: number; } // 处理数据的操作类,每个方法对应严格类型的参数 class Operator { public processA(obj: A) { console.log('create'); } public processB(obj: B) { console.log('edit'); } } // Operator中所有操作,以及动态调用的输入集合 type Operations = 'processA' | 'processB'; type InputA = { operation: 'processA', obj: A; } type InputB = { operation: 'processB', obj: B; } type Input = InputA | InputB; // 这段代码可正常运行 const action: Input = { operation: 'processB', obj: { bar: 'abc', baz: 1 } }; // 具体操作实例 const operator = new Operator(); operator[action.operation](action.obj); // 对具体action变量可正常调用 // 这段代码无法运行 function fixHerePlease(action: Input) { const operator = new Operator(); operator[action.operation](action.obj); // 以action为参数时无法工作 }
错误信息(翻译后)
参数类型“A | B”无法赋值给类型“B & A”。类型“A”无法赋值给类型“B & A”。类型“A”缺少类型“B”中的以下属性:bar、baz
解决方案
核心问题是TypeScript无法自动关联联合类型中operation和obj的对应关系。我们可以通过泛型+映射类型让TypeScript正确推断类型关联,无需any或if分支:
// 完全不同的接口,字段各异 interface A { foo: boolean; } interface B { bar: string; baz: number; } // 处理数据的操作类,每个方法对应严格类型的参数 class Operator { public processA(obj: A) { console.log('create'); } public processB(obj: B) { console.log('edit'); } } // 自动提取Operator方法的参数类型映射 type OperatorMethods = typeof Operator.prototype; type OperationParamMap = { [K in keyof OperatorMethods]: Parameters<OperatorMethods[K]>[0]; }; // 定义带泛型的Input类型,确保operation和obj的类型关联 type Input<K extends keyof OperationParamMap = keyof OperationParamMap> = { operation: K; obj: OperationParamMap[K]; }; // 这段代码可正常运行 const action: Input = { operation: 'processB', obj: { bar: 'abc', baz: 1 } }; const operator = new Operator(); operator[action.operation](action.obj); // 修复后的函数,可正常工作 function fixHerePlease<K extends keyof OperationParamMap>(action: Input<K>) { const operator = new Operator(); operator[action.operation](action.obj); }
说明
OperationParamMap通过映射类型自动提取Operator类所有方法的第一个参数类型,无需手动维护操作与参数的对应关系- 泛型
Input<K>确保operation的类型与obj的类型严格绑定 - 函数
fixHerePlease使用泛型K,让TypeScript能根据传入的action推断出对应的方法和参数类型,完全类型安全
内容的提问来源于stack exchange,提问作者Mike
相关产品推荐
相关产品推荐

