TypeScript增强对象时如何保留原有函数的完整类型定义
解决方案
核心思路
你原先的泛型定义将所有属性值统一为单一类型V,会丢失每个属性独有的函数参数、返回值类型。正确做法是用单个泛型承接整个输入对象的完整类型,再通过边界约束保证所有属性都是符合要求的返回对象的函数,即可完整保留原有结构的类型定义。
基础实现(完全保留原有函数类型)
// 定义边界约束:所有属性值都是接收任意参数、返回对象的函数 type FunctionReturningObject = (...args: any[]) => object; // 泛型直接承接输入对象的完整类型,返回值和输入类型一致 function augmentObject<T extends Record<string, FunctionReturningObject>>(simpleObject: T): T { // 此处写你的转换逻辑 // 示例:如果需要包裹原函数,可按如下方式处理,类型不会丢失 const result = {} as T; for (const key in simpleObject) { result[key] = ((...args) => { // 自定义增强逻辑 const originalResult = simpleObject[key](...args); return originalResult; }) as T[typeof key]; } return result; } // 测试验证 const simpleObject = { one: () => ({}), two: (a: number) => ({ a }), }; // 类型完全保留 augmentObject(simpleObject).one; // 类型为 () => {} augmentObject(simpleObject).two; // 类型为 (a: number) => { a: number }
扩展实现(给每个函数返回值追加额外属性类型)
如果你的转换逻辑会给每个函数返回的对象追加固定属性,可以用映射类型修改返回值定义,同时保留原函数参数类型:
type FunctionReturningObject = (...args: any[]) => object; // 定义单函数增强后的类型:保留参数,返回值追加额外属性 type AugmentedFn<T extends FunctionReturningObject> = (...args: Parameters<T>) => ReturnType<T> & { extraField: string }; // 定义整个对象增强后的类型 type AugmentedObject<T extends Record<string, FunctionReturningObject>> = { [K in keyof T]: AugmentedFn<T[K]> } function augmentObject<T extends Record<string, FunctionReturningObject>>(simpleObject: T): AugmentedObject<T> { const result = {} as AugmentedObject<T>; for (const key in simpleObject) { result[key] = ((...args) => { const originalResult = simpleObject[key](...args); // 增强逻辑:追加额外属性 return { ...originalResult, extraField: 'test' }; }) as AugmentedFn<T[typeof key]>; } return result; } // 测试验证 augmentObject(simpleObject).two(123).extraField; // 可正常识别extraField类型为string
内容的提问来源于stack exchange,提问作者mre
相关产品推荐
相关产品推荐

