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

TypeScript中如何仅保留单个of方法,避免联合类型函数重载冗余

解决方案:用条件类型+类型守卫实现单签名of方法

基础类型定义

先明确核心类型:

// 原生双参数函数类型
type FFunction2<T1, T2, R> = (a: T1, b: T2) => R;

// 包装器类
class Function2<T1, T2, R> {
  private fn: FFunction2<T1, T2, R>;

  private constructor(fn: FFunction2<T1, T2, R>) {
    this.fn = fn;
  }

  apply(a: T1, b: T2): R {
    return this.fn(a, b);
  }

  // 单实现of方法,自动适配原生函数/包装器实例
  static of<T extends FFunction2<any, any, any> | Function2<any, any, any>>(
    fn: T
  ): T extends FFunction2<infer T1, infer T2, infer R> 
    ? Function2<T1, T2, R> 
    : T {
    // 运行时类型判断
    if (fn instanceof Function2) {
      return fn as T;
    }
    return new Function2(fn) as ReturnType<typeof Function2.of<T>>;
  }
}

// 联合类型,统一管理原生函数和包装器
type TFunction2<T1, T2, R> = FFunction2<T1, T2, R> | Function2<T1, T2, R>;

关键逻辑说明

  1. 条件类型自动推导:
    通过T extends FFunction2<infer T1, infer T2, infer R> ? Function2<T1, T2, R> : T,TypeScript会自动判断传入参数的类型:

    • 如果是原生FFunction2,返回包装后的Function2实例;
    • 如果已经是Function2实例,直接返回原对象,避免重复包装。
  2. 运行时类型守卫:
    用fn instanceof Function2做运行时判断,确保逻辑分支正确,避免类型断言出错。

  3. 自动泛型推导:
    不需要手动指定泛型参数,TypeScript会从传入的fn自动推导T1、T2、R的类型。

测试示例

// 测试原生函数包装
const add = (a: number, b: number): number => a + b;
const wrappedAdd = Function2.of(add); // 自动推导为Function2<number, number, number>
console.log(wrappedAdd.apply(2, 3)); // 输出5

// 测试已有包装器实例
const concatWrapper = new Function2((x: string, y: string) => x + y);
const sameWrapper = Function2.of(concatWrapper); // 自动推导为Function2<string, string, string>
console.log(sameWrapper.apply("hello", " world")); // 输出hello world

扩展到其他参数数量的映射器

如果需要给Function1、Function3等实现同样逻辑,只需复用条件类型+类型守卫的模式,比如把类型守卫抽成通用函数:

function isFunction2Instance<T1, T2, R>(fn: any): fn is Function2<T1, T2, R> {
  return fn instanceof Function2;
}

然后在Function2.of中调用这个函数,代码更易维护。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 12:10:09