TypeScript中如何复制泛型结构并将原值替换为自定义值
问题根因
你的实现存在两个核心问题:
- reduce累加逻辑错误:你在分支判断后直接返回了单个转换函数,相当于每次都把整个累加对象替换成了单个函数,完全不符合构造输出对象的需求
- 泛型场景下的类型推导限制:TypeScript无法自动关联泛型
Input的属性类型和转换后输出的属性类型,需要做合理的类型断言保证类型兼容
修正后的完整实现
// 首先定义基础类型 type OutputValue<T> = (val: T) => void; type OutputType<T> = { [k in keyof T]: OutputValue<T[k]> }; // 定义类型守卫 function isString(val: unknown): val is string { return typeof val === 'string'; } function isNumber(val: unknown): val is number { return typeof val === 'number'; } // 转换函数 const transformString = (stringValue: string): OutputValue<string> => { return (val: string) => { // 处理val的业务代码 console.log('处理字符串', val); } } const transformNumber = (numberValue: number): OutputValue<number> => { return (val: number) => { // 处理val的业务代码 console.log('处理数字', val); } } // 核心转换实现 const transformationFunction = function<Input extends Record<string, any>>(input: Input): OutputType<Input> { const keys = Object.keys(input) as Array<keyof Input>; return keys.reduce((output, key) => { const inputValue = input[key]; if (isString(inputValue)) { // 类型守卫确认是string,断言为对应输出类型赋值 output[key] = transformString(inputValue) as OutputType<Input>[keyof Input]; } else if (isNumber(inputValue)) { // 类型守卫确认是number,断言为对应输出类型赋值 output[key] = transformNumber(inputValue) as OutputType<Input>[keyof Input]; } else { throw new Error("无匹配转换规则"); } // 返回完整的累加对象,而不是单个函数 return output; }, {} as OutputType<Input>) }
验证使用
// 测试用例 const input = { age: 18, surname: '张三' }; const output = transformationFunction(input); // 可正常触发智能提示,类型安全 output.age(20); output.surname('李四');
关键改动说明
- 去掉了不必要的
Output泛型参数:输出类型完全由输入类型决定,直接返回OutputType<Input>即可,简化类型定义 - 修正了reduce的累加逻辑:每次给当前key对应的属性赋值后返回完整的累加对象,符合构造输出对象的需求
- 合理的类型断言:在已经通过类型守卫确认值类型的前提下做断言,既解决了编译器报错问题,也不会破坏类型安全,外部调用依然可以获得完整的类型提示和校验
内容的提问来源于stack exchange,提问作者sookie
相关产品推荐
相关产品推荐

