如何基于不可修改的函数对象创建带扩展参数的TypeScript Record
TypeScript 扩展函数参数并保留原对象键类型匹配
首先是无法修改的原函数对象定义:
const _fns = { doA: (arg: string): void => someFuncA(arg), doB: (arg: number): void => someFuncB(arg) }; // 示例依赖函数 function someFuncA(arg: string) {} function someFuncB(arg: number) {}
需求
- 新对象必须包含
_fns的所有键 - 每个函数的参数列表需要在原有参数前新增一个
Event类型的参数,比如原函数doC: (arg: boolean) => void要扩展为doC: (e: Event, arg: boolean) => void
实现方案
直接用Record无法满足每个键对应不同扩展函数类型的需求,需要定义一个映射泛型类型来动态扩展每个函数的参数:
// 泛型类型:为每个函数的参数列表前置一个Event类型参数 type ExtendFunctionParams<T> = { [K in keyof T]: T[K] extends (...args: infer Args) => infer Return ? (e: Event, ...args: Args) => Return : T[K]; };
然后用这个类型定义新对象,TypeScript会自动推导每个函数的参数类型:
const newFns: ExtendFunctionParams<typeof _fns> = { doA: (e, arg) => { // e 类型自动推导为 Event,arg 为 string someOtherFunctionForA(e, arg); }, doB: (e, arg) => { // e 类型自动推导为 Event,arg 为 number someOtherFunctionForB(e, arg); } }; // 示例扩展后的函数 function someOtherFunctionForA(e: Event, arg: string) {} function someOtherFunctionForB(e: Event, arg: number) {}
原理说明
- 映射类型
[K in keyof T]遍历原对象的所有键 - 通过
extends (...args: infer Args) => infer Return判断并提取原函数的参数列表Args和返回值Return - 构造新的函数类型,在原参数列表前添加
Event类型参数,保持返回值不变
内容的提问来源于stack exchange,提问作者traxx2012
相关产品推荐
相关产品推荐

