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

TypeScript:基于回调参数数量实现返回类型重载的问题

解决TypeScript中根据组件参数自动区分memo/forwardRef包装的类型问题

问题根源

你遇到的核心问题是TypeScript的重载匹配逻辑:当显式指定泛型<Props>时,TS会优先尝试匹配第一个重载定义,忽略传入函数的参数长度,导致第二个重载的参数被错误推断为any。普通重载无法根据函数参数数量自动区分两种场景,需要通过条件类型+泛型约束来实现精准的类型推断。

解决方案代码

type AnyObject = Record<string, unknown>;
type EmptyObject = Record<string, never>;
type RenderResult = null; // 实际替换为React.ReactElement | null
type RefType = string; // 实际替换为React.ForwardedRef<T>

// 辅助类型:判断组件函数是否接收ref参数
type HasRef<Func> = Func extends (props: any, ref: RefType) => RenderResult ? true : false;

// 辅助类型:提取组件函数的Props参数类型
type ExtractProps<Func> = Func extends (props: infer P) => RenderResult ? P : never;

// 重构后的Test函数,用条件类型动态返回对应类型
function Test<Func extends (props: any, ...args: any[]) => RenderResult>(
  Component: Func
): HasRef<Func> extends true 
  ? (props: ExtractProps<Func> & { ref: RefType }) => RenderResult 
  : (props: ExtractProps<Func>) => RenderResult;

function Test(Component: (...args: any[]) => RenderResult) {
  // 运行时根据参数长度选择包装逻辑
  if (Component.length === 2) {
    // 实际场景替换为:return memo(forwardRef(Component))
    return (props: any) => {
      const { ref, ...restProps } = props;
      return Component(restProps, ref);
    };
  } else {
    // 实际场景替换为:return memo(Component)
    return Component;
  }
}

// 测试用例
type Props = { a: string };

// 符合预期:x的类型为 (props: Props) => null,props参数类型正确
const x = Test((props: Props) => null);

// 符合预期:y的类型为 (props: Props & { ref: string }) => null,props和ref类型均正确
const y = Test((props: Props, ref: RefType) => null);

// 显式指定泛型的场景也能正常工作
const z = Test<(props: Props) => RenderResult>((props) => null);
const w = Test<(props: Props, ref: RefType) => RenderResult>((props, ref) => null);

方案说明

  1. 辅助类型做判断:通过HasRef判断传入的组件函数是否包含ref参数,ExtractProps自动提取组件的Props类型,避免手动指定泛型的冗余。
  2. 条件类型动态返回:单个函数定义结合条件返回类型,让TypeScript根据传入函数的结构自动匹配对应的返回类型,彻底解决重载匹配歧义问题。
  3. 运行时兼容逻辑:通过Component.length判断参数数量,对应执行memo或memo(forwardRef)的包装逻辑,和类型系统保持一致。

内容的提问来源于stack exchange,提问作者GreenTea222

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 22:28:34