如何基于TypeScript Mapped Types生成重载Getter函数类型
实现方案
你需要先定义两个工具类型:首先是经典的联合类型转交叉类型工具,再基于它把对象每个属性映射为单参数函数签名后合并,最终得到等价于重载的函数类型。
完整代码示例
// 联合类型转交叉类型的工具类型,核心是利用函数参数的逆变特性 type UnionToIntersection<U> = (U extends any ? (k: U) => void : never) extends ((k: infer I) => void) ? I : never; // 从传入的对象类型生成对应重载get函数的类型 type GetFunction<T> = UnionToIntersection<{ [K in keyof T]: (k: K) => T[K] }[keyof T]>; // 测试用的Person接口 interface Person { name: string; age: number; location: string; } // 生成Person对应的get函数类型 type PersonGetFn = GetFunction<Person>; // 给get函数应用生成的类型 const get: PersonGetFn = (k: keyof Person) => { // 内部实现逻辑示例,可根据实际需求调整 const mockPerson = { name: '张三', age: 20, location: '北京' }; return mockPerson[k]; } // 测试自动类型推导 const name = get('name'); // 自动推导为string类型 const age = get('age'); // 自动推导为number类型 const location = get('location'); // 自动推导为string类型
实现说明
UnionToIntersection是TS中常用的工具类型,利用函数参数的逆变位置特性,可以把形如((k: 'a') => void) | ((k: 'b') => void)的联合类型转换为((k: 'a') => void) & ((k: 'b') => void)的交叉类型,而函数类型的交叉在TS中等价于函数重载。GetFunction先通过映射类型把输入对象的每个属性转换为(k: 键名) => 键值类型的函数签名,再通过索引访问[keyof T]把所有函数签名转为联合类型,最后传入UnionToIntersection转为交叉类型,就得到了你要的重载函数签名。
如果需要适配任意对象的泛型getter工厂,可以直接封装为泛型函数:
function createGetter<T>(target: T): GetFunction<T> { return ((k: keyof T) => target[k]) as GetFunction<T>; } // 使用示例 const person = { name: '李四', age: 25, location: '上海' }; const getPerson = createGetter(person); const age = getPerson('age'); // 推导为number类型
内容的提问来源于stack exchange,提问作者CMCDragonkai
相关产品推荐
相关产品推荐

