You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何拆分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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.28 09:57:04