如何在TypeScript映射类型中保留泛型信息?
解决TypeScript泛型处理器方法的Proxy类型映射问题
要保留原类泛型方法中的泛型信息,需要调整Mapper类型,使其能够识别并保留泛型函数的参数结构。
解决方案代码
type InputRef<T> = { current: T, }; type OutputRef<T> = { current?: T, }; class Original { increment(input: InputRef<number>, output: OutputRef<number>) { const { current: inValue } = input; output.current = inValue + 1; } toBox<T>(input: InputRef<T>, output: OutputRef<{ boxed: T }>) { const { current: inValue } = input; output.current = { boxed: inValue }; } // 测试多泛型参数场景 pairBox<T, U>(input: InputRef<[T, U]>, output: OutputRef<{ first: T, second: U }>) { const { current: [a, b] } = input; output.current = { first: a, second: b }; } } // 调整后的Mapper,支持泛型函数 type Mapper<Fn> = Fn extends <...GenericArgs>(input: InputRef<infer U>, output: OutputRef<infer V>) => unknown ? <...GenericArgs>(input: U) => V : never; type MyProxyGeneratedByThirdPartyJs = { [FnName in keyof Original]: Mapper<Original[FnName]> }; declare const proxy: MyProxyGeneratedByThirdPartyJs; // 测试调用 const numResult = proxy.increment(3); // number (4) const numBox = proxy.toBox(3); // { boxed: number } const strBox = proxy.toBox('hello'); // { boxed: string } const pairBox = proxy.pairBox([1, 'test']); // { first: number, second: string }
原理说明
原Mapper类型仅处理非泛型函数,遇到泛型方法时TypeScript会将泛型参数默认推断为unknown。调整后的Mapper通过以下方式解决问题:
- 使用
<...GenericArgs>捕获原方法的所有泛型参数(支持单个或多个泛型) - 在条件类型中匹配泛型函数的结构,将输入参数从
InputRef<U>简化为U,输出类型保留原OutputRef中的V - 返回与原方法泛型参数一致的函数类型,确保调用时泛型信息能正确传递
内容的提问来源于stack exchange,提问作者tonychow1997
相关产品推荐
相关产品推荐

