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

如何移除TypeScript多调用签名接口中的指定调用签名

问题原因

之前用Exclude失败的根本原因有两点:

  • 多调用签名的接口是重载函数类型,不是联合类型,而Exclude是专门用来过滤联合类型成员的工具,本身不支持重载签名的细粒度剔除。
  • 直接对整个重载接口做类型匹配时,TS会判定整个重载类型可赋值给你传入的待排除单签名,最终Exclude直接返回never,其余签名完全丢失。
正确实现方案

核心思路是利用TS对重载函数做条件类型推断时,会逐个遍历调用签名分发处理的特性,先过滤掉需要替换的旧签名,再交叉合并新签名即可。

通用签名过滤实现

先定义通用的重载调用签名过滤工具类型:

type RemoveCallSignature<T, TargetSignature> =
  T extends (...args: infer Args) => infer Return
    ? TargetSignature extends (...args: Args) => infer TargetReturn
      ? Return extends TargetReturn
        ? Args extends Parameters<TargetSignature>
          ? never
          : (...args: Args) => Return
        : (...args: Args) => Return
      : (...args: Args) => Return
    : never;

使用方式:

// 1. 剔除旧的authorize调用签名
type FilteredBase = RemoveCallSignature<Foo, (options: {method: 'authorize', userId: number}) => Promise<string>>;

// 2. 合并新签名,得到最终的Bar类型
type Bar = FilteredBase & ((options: {method: 'authorize', userToken: string}) => Promise<string>);

场景化简化实现

如果你的重载签名都是以{method: 字面量类型}作为入参格式,可以写更简洁的按method值过滤的工具类型,避免通用类型比对的边缘兼容问题:

type RemoveSignatureByMethod<T, MethodType extends string> =
  T extends (options: infer Options) => infer Return
    ? Options extends {method: MethodType}
      ? never
      : (options: Options) => Return
    : never;

// 使用
type FilteredBase2 = RemoveSignatureByMethod<Foo, 'authorize'>;
type Bar2 = FilteredBase2 & ((options: {method: 'authorize', userToken: string}) => Promise<string>);
效果验证
declare const bar: Bar;
// 新authorize签名正常,要求传userToken
bar({method: 'authorize', userToken: 'test_token'}); // 类型校验通过
// 旧authorize签名已被移除,传userId会报错
// bar({method: 'authorize', userId: 123}); // 类型报错
// deauthorize签名完整保留
bar({method: 'deauthorize', authToken: 'test_auth'}); // 类型校验通过

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.26 14:33:30