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

TypeScript:如何传递联合类型参数并保留函数重载签名?

TypeScript重载与联合类型的两个常见问题及解决方法

问题1:子类调用父类重载方法时联合类型参数报错

问题描述

子类Collection的del方法传递联合类型T | ((v: T) => boolean)给父类Enumerable的重载index方法时,TypeScript无法匹配任何一个重载分支,抛出类型错误。

解决方法

TypeScript的重载解析不会自动将联合类型拆分为对应的重载分支,需要手动通过类型守卫区分参数类型,分别匹配重载:

方案1:基础类型守卫(适用于T非函数类型场景)

class Enumerable<T> {
  index(v: T): number | undefined
  index(op: (v: T) => boolean): number | undefined
  index(op: T | ((v: T) => boolean)): number | undefined {
    return 0
  }
}

class Collection<T> extends Enumerable<T> {
  del(v: T | ((v: T) => boolean)): void {
    const i = typeof v === 'function' 
      ? this.index(v as (v: T) => boolean) 
      : this.index(v);
    console.log(i);
  }
}

new Collection<number>().del(0); // 正常运行

方案2:自定义类型守卫(适用于T可能为函数类型场景)

如果泛型T本身可能是函数类型,基础的typeof判断无法区分,需要自定义类型守卫:

function isDeletePredicate<T>(val: T | ((v: T) => boolean)): val is ((v: T) => boolean) {
  // 可根据实际逻辑添加更严格判断,比如检查参数个数
  return typeof val === 'function' && (val as Function).length === 1;
}

class Collection<T> extends Enumerable<T> {
  del(v: T | ((v: T) => boolean)): void {
    const i = isDeletePredicate(v) ? this.index(v) : this.index(v);
    console.log(i);
  }
}

问题2:联合类型回调参数导致类型推断异常

问题描述

当order方法的参数是联合类型((a: T, b: T) => number) | ((v: T) => unknown)时,传入回调(pairs) => pairs[0]会出现参数隐式any的错误,TypeScript无法推断参数类型。

解决方法

将联合类型参数改为函数重载,让TypeScript根据传入的回调自动匹配对应的重载分支,从而正确推断参数类型:

class Collection<T> {
  // 重载签名
  order(): T[];
  order(op: (a: T, b: T) => number): T[];
  order(op: (v: T) => unknown): T[];
  // 实现签名
  order(op?: ((a: T, b: T) => number) | ((v: T) => unknown)): T[] {
    return [];
  }
}

new Collection<[number, number]>()
  .order((pairs) => pairs[0]); // pairs自动推断为[number, number]

通过重载,TypeScript会识别传入的回调属于(v: T) => unknown分支,进而正确推断pairs的类型为T(即[number, number])。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 00:03:20