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

如何为Mocha多态函数noCI编写正确的TypeScript泛型?

问题分析与解决方案

为什么首次尝试的返回类型不符合预期?

你的泛型约束T extends Mocha.SuiteFunction | Mocha.TestFunction会让TypeScript将itOrDescribe的类型视为两个类型的联合类型。当访问itOrDescribe.skip时,TypeScript会计算联合类型的属性访问结果——也就是Mocha.PendingSuiteFunction | Mocha.PendingTestFunction。由于TypeScript无法针对T的具体子类型(是SuiteFunction还是TestFunction)分别推导返回类型,最终只能给出最宽泛的联合结果,导致无论传入哪种类型,返回类型都被推断为两种pending类型的联合。

正确的类型注解方案

方案1:函数重载(推荐,可读性更高)

通过函数重载可以明确指定不同输入对应的输出类型,完全匹配你的需求:

// 重载签名:定义输入输出的对应关系
function noCI(itOrDescribe: Mocha.SuiteFunction): Mocha.SuiteFunction | Mocha.PendingSuiteFunction;
function noCI(itOrDescribe: Mocha.TestFunction): Mocha.TestFunction | Mocha.PendingTestFunction;
// 实现签名:处理逻辑
function noCI(itOrDescribe: Mocha.SuiteFunction | Mocha.TestFunction) {
  return isCI ? itOrDescribe.skip : itOrDescribe;
}

当传入describe(SuiteFunction类型)时,返回类型自动推断为SuiteFunction | PendingSuiteFunction;传入it(TestFunction类型)时,返回类型为TestFunction | PendingTestFunction。

方案2:泛型+条件类型

如果需要用泛型实现,可以通过条件类型动态映射输入到对应的派生类型:

// 定义输入类型到pending类型的映射
type PendingType<T> = 
  T extends Mocha.SuiteFunction ? Mocha.PendingSuiteFunction :
  T extends Mocha.TestFunction ? Mocha.PendingTestFunction :
  never;

const noCI = <T extends Mocha.SuiteFunction | Mocha.TestFunction>(
  itOrDescribe: T
): T | PendingType<T> => {
  // 需要类型断言,因为TS无法自动推断skip的类型匹配PendingType<T>
  return isCI ? itOrDescribe.skip : itOrDescribe as T | PendingType<T>;
};

泛化问题的解决思路

要实现“接收类型A或B,返回对应派生类型”的需求,核心是让TypeScript建立输入类型与输出类型的一一对应关系,常用两种方式:

  • 函数重载:为每个输入类型单独定义签名,适合类型分支少的场景,代码直观易读。
  • 泛型+条件类型:通过T extends A ? X : T extends B ? Y : ...的条件逻辑动态映射类型,适合分支多或需要复用类型逻辑的场景。

注意:如果A和B存在类型重叠,需要确保它们有可区分的特征(比如独特的属性、字面量类型),否则TypeScript无法准确推断对应的派生类型。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.13 06:16:33