TypeScript泛型Proxyify:如何包装接口修改函数返回值?
解决方法:用映射类型 + 条件类型修改接口函数返回值
这问题我熟,用TypeScript的映射类型结合条件类型就能完美实现你要的效果,一步步来给你拆解:
首先,我们需要一个工具类型来单独处理函数的返回值——它会保留原函数的参数列表,只把返回值扩展成「原返回值 | string」:
// 处理单个函数类型,修改其返回值 type ModifyFunctionReturn<Func> = Func extends (...args: infer Args) => infer OriginalReturn ? (...args: Args) => OriginalReturn | string : Func;
这里用了TypeScript的infer关键字,自动提取原函数的参数列表Args和原返回值OriginalReturn,然后返回一个参数完全一致、返回值多了string类型的新函数类型。
接下来,用映射类型遍历原接口的所有属性,把上面的工具类型应用到每个属性上:
// 遍历接口的每个属性,批量修改函数返回值 type ModifyInterfaceReturn<Interface> = { [Key in keyof Interface]: ModifyFunctionReturn<Interface[Key]>; };
这个泛型类型会遍历传入接口的每个键Key,对每个属性Interface[Key](也就是接口里的每个函数)执行返回值修改操作,同时还会自动保留原接口的可选属性(比如anotherTest?的可选性不会丢失)。
最后,把你的原接口传入这个泛型,就能得到你想要的修改后接口:
// 原接口 interface IBaseInterface { test(a?: boolean, b?: number): Promise<boolean>; anotherTest?(a?: number): Promise<number>; } // 生成修改后的接口类型 type IBaseInterfaceModified = ModifyInterfaceReturn<IBaseInterface>;
现在你可以验证一下,IBaseInterfaceModified的结构完全符合你的需求:
test(a?: boolean, b?: number): Promise<boolean> | stringanotherTest?(a?: number): Promise<number> | string
甚至可以写个测试代码确认类型是否生效:
const demo: IBaseInterfaceModified = { test: async (a, b) => { if (a) return true; return "操作失败"; // 允许返回string类型 }, anotherTest: (a) => { if (a) return Promise.resolve(100); return "数值无效"; // 同样允许返回string } };
内容的提问来源于stack exchange,提问作者Pat
相关产品推荐
相关产品推荐

