如何拆分React组件泛型Props并为返回结果提供强类型支持
问题根因
这是 TypeScript 泛型推导的固有限制:当泛型参数 T 未被具体类型实例化时,TS 类型系统无法自动识别 Omit<CustomType<T>, 'aBunchOfProps'> 和 React.ComponentPropsWithoutRef<T> 是等价类型,哪怕你已经通过 Equals 工具类型验证了所有实际场景下二者完全相等,静态推导阶段也会报类型不匹配错误。
解决方案1:类型断言(最简便)
直接在解构得到的 componentProps 后加类型断言即可,你之前调用时出现 any 类型是因为泛型推导上下文缺失,补充正确的泛型约束即可解决:
import React, { ComponentPropsWithoutRef, ElementType } from "react"; type CustomType<T extends ElementType> = ComponentPropsWithoutRef<T> & { aBunchOfProps: string; }; const partitionProps = <T extends ElementType>( props: CustomType<T> ): { customProps: { aBunchOfProps: string }, componentProps: ComponentPropsWithoutRef<T> } => { const { aBunchOfProps, ...componentProps } = props; return { customProps: { aBunchOfProps }, // 此处添加类型断言即可解决报错 componentProps: componentProps as ComponentPropsWithoutRef<T> }; };
实际使用示例(不会出现any类型):
// 定义支持as prop的通用组件 type MyWrapperProps<T extends ElementType = 'div'> = CustomType<T> & { as?: T; }; function MyWrapper<T extends ElementType = 'div'>({ as, ...rawProps }: MyWrapperProps<T>) { const { customProps, componentProps } = partitionProps(rawProps as CustomType<T>); const Component = as || 'div'; // componentProps 会正确匹配当前 Component 对应的属性类型,不会为any return <Component {...componentProps} />; } // 测试使用 <MyWrapper as="a" href="/test" aBunchOfProps="test" /> // 类型校验正常
解决方案2:调整返回值类型定义(无断言)
如果不想使用类型断言,也可以直接用 Omit 定义返回的 componentProps 类型,因为你已经验证过该类型和 ComponentPropsWithoutRef<T> 完全等价,实际使用时没有任何兼容问题:
const partitionProps = <T extends ElementType>( props: CustomType<T> ): { customProps: { aBunchOfProps: string }, componentProps: Omit<CustomType<T>, 'aBunchOfProps'> } => { const { aBunchOfProps, ...componentProps } = props; return { customProps: { aBunchOfProps }, componentProps }; };
内容的提问来源于stack exchange,提问作者zprobinson
相关产品推荐
相关产品推荐

