TypeScript调用泛型函数时如何关联泛型参数P与T?
解决React Forward Ref泛型关联丢失的问题
这个问题我之前也碰到过,核心原因是你用的立即执行函数(IIFE)在返回时,TypeScript把泛型参数的关联性给抹平了,咱们一步步拆解解决:
问题根源
你写的IIFE写法:
const MyCom = (<P extends keyof typeof OBJ>() => { return react_forward_ref<P, Parameters<typeof OBJ[P]>[0]>((props, ref) => null) })()
TypeScript执行这个IIFE的时候,泛型P没有外部参数约束,会直接被推断成keyof typeof OBJ(也就是'a'|'b'|'c')。这就导致原本P和Parameters<typeof OBJ[P]>[0]的一一对应关系,被变成了keyof typeof OBJ对应所有ref类型的联合,自然就失去了准确的类型校验能力。
最简单的修复方案:去掉IIFE,直接声明泛型
不需要用IIFE包裹,直接把泛型参数定义在react_forward_ref的调用层级上,让TypeScript保留P和ref类型的关联:
const OBJ = { a: (_: number) => _, b: (_: string) => _, c: (_: object) => _, } function react_forward_ref<P, T>(fn: (props: P, ref: T) => any) { return fn } // 直接在react_forward_ref调用时绑定泛型关联 const MyCom = react_forward_ref(<P extends keyof typeof OBJ>(props: P, ref: Parameters<typeof OBJ[P]>[0]) => null)
现在MyCom的类型就和你预期的完全一致:<P extends keyof typeof OBJ>(props: P, ref: Parameters<typeof OBJ[P]>[0]) => null。试试调用MyCom('a', '字符串'),TypeScript会正确提示你需要传入number类型的ref。
进阶优化:让react_forward_ref本身支持关联类型
如果你想让react_forward_ref的调用更简洁,可以修改它的类型定义,让ref类型自动依赖于props类型:
// 重新定义react_forward_ref,让T自动关联P的类型 function react_forward_ref< P extends keyof typeof OBJ, T = Parameters<typeof OBJ[P]>[0] >(fn: (props: P, ref: T) => any) { return fn } // 使用时无需手动写泛型,TypeScript会自动推断关联 const MyCom = react_forward_ref((props, ref) => null)
这种写法下,MyCom的类型依然能保持正确的关联,调用时的类型校验也完全正常。
内容的提问来源于stack exchange,提问作者xialvjun
相关产品推荐
相关产品推荐

