TypeScript中嵌套函数包装类型调用的类型错误解决方案咨询
解决TypeScript包装函数的类型错误
问题背景
现有两个参数类型不同但返回类型均为CommonRes的函数logicA、logicB,需要实现:
- 以键值对形式访问这些函数
- 对每个函数的结果统一应用相同的后置处理逻辑
尝试的实现代码如下:
type ParamsA = { somethingFromParamsA: string }; type ParamsB = { somethingFromParamsB: string }; type CommonRes = { /* 定义你的返回结构 */ }; const logicA = (params: ParamsA): CommonRes => { /* 实现逻辑 */ }; const logicB = (params: ParamsB): CommonRes => { /* 实现逻辑 */ }; type PostprocessorFn = (res: CommonRes) => Promise<string>; const postprocessing = async (res: CommonRes) => { const someResultString = await something(...); // 实际异步逻辑 return someResultString; }; const wrappedLogic = new Proxy({ a: (wrapper: PostprocessorFn) => (params: ParamsA) => wrapper(logicA(params)), b: (wrapper: PostprocessorFn) => (params: ParamsB) => wrapper(logicB(params)), }, { get(target, key) { return target[key](postprocessing); } });
调用wrappedLogic.a({somethingFromParamsA: 'some'})时,出现TypeScript错误:
Argument of type {somethingFromParamsA: string} is not assignable to parameter of type 'PostprocessorFn'. Object literal may only specify known properties, and 'somethingFromParamsA' does not exist in type 'PostprocessorFn'
错误原因
TypeScript无法自动推断Proxy返回对象的实际类型,它错误地认为wrappedLogic.a是Proxy目标对象中接受PostprocessorFn的函数,而非调用该函数并传入postprocessing后返回的、接受ParamsA的函数。因此传入参数时会触发类型不匹配错误。
解决方案
方案1:直接生成包装对象(推荐,无需Proxy)
跳过Proxy,直接创建已绑定后置处理逻辑的对象,类型推断自然生效:
type ParamsA = { somethingFromParamsA: string }; type ParamsB = { somethingFromParamsB: string }; type CommonRes = { /* 定义你的返回结构 */ }; const logicA = (params: ParamsA): CommonRes => { /* 实现逻辑 */ }; const logicB = (params: ParamsB): CommonRes => { /* 实现逻辑 */ }; const postprocessing = async (res: CommonRes): Promise<string> => { const someResultString = await something(...); // 实际异步逻辑 return someResultString; }; // 直接生成包装后的函数集合 const wrappedLogic = { a: (params: ParamsA) => postprocessing(logicA(params)), b: (params: ParamsB) => postprocessing(logicB(params)), }; // 正确调用 wrappedLogic.a({somethingFromParamsA: 'some'});
方案2:为Proxy手动指定类型
若必须使用Proxy,需手动定义wrappedLogic的期望类型并通过类型断言修正:
type ParamsA = { somethingFromParamsA: string }; type ParamsB = { somethingFromParamsB: string }; type CommonRes = { /* 定义你的返回结构 */ }; const logicA = (params: ParamsA): CommonRes => { /* 实现逻辑 */ }; const logicB = (params: ParamsB): CommonRes => { /* 实现逻辑 */ }; type PostprocessorFn = (res: CommonRes) => Promise<string>; const postprocessing = async (res: CommonRes) => { const someResultString = await something(...); // 实际异步逻辑 return someResultString; }; // 定义期望的包装后类型 type WrappedLogic = { a: (params: ParamsA) => Promise<string>; b: (params: ParamsB) => Promise<string>; }; const wrappedLogic = new Proxy({ a: (wrapper: PostprocessorFn) => (params: ParamsA) => wrapper(logicA(params)), b: (wrapper: PostprocessorFn) => (params: ParamsB) => wrapper(logicB(params)), }, { get(target, key: keyof typeof target) { return target[key](postprocessing); } }) as WrappedLogic; // 手动断言类型 // 正确调用 wrappedLogic.a({somethingFromParamsA: 'some'});
内容的提问来源于stack exchange,提问作者Sergey L
相关产品推荐
相关产品推荐

