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

TypeScript中如何从泛型回调数组正确推断返回联合类型?

解决TypeScript中createUnion函数的联合类型推断问题

问题根源

你当前的createUnion函数泛型定义为<Creation>,要求所有回调函数的返回类型都兼容Creation。当回调返回类型存在子类型关系时(比如string和null),TypeScript能自动推断出Creation为两者的联合类型;但当返回类型无直接子类型关系时(比如string和number),TypeScript无法找到公共兼容类型,会默认以第一个回调的返回类型作为Creation,导致后续回调类型不匹配报错。

修正方案

修改泛型定义,让TypeScript捕获数组中每个回调的具体类型,再提取所有返回类型的联合:

function createUnion<T extends (() => unknown)[]>(creators: [...T]): ReturnType<T[number]> {
  const index = Math.floor(Math.random() * creators.length);
  return creators[index]();
}

关键改动说明

  1. T extends (() => unknown)[]:泛型T约束为函数数组,捕获每个回调的具体类型
  2. [...T]:使用剩余元组语法,强制TypeScript推断数组中每个元素的精确类型,而非模糊的联合类型数组
  3. ReturnType<T[number]>:提取数组中所有函数的返回类型,自动组合为联合类型

验证修正结果

将修正后的函数替换原代码,所有测试用例都能正确推断联合类型:

function createNumber(): number {
  return 42;
}

function createString(): string {
  return 'Hello';
}

function createNull(): null {
  return null;
}

function createUndefined(): undefined {
  return undefined;
}

function createBoolean(): boolean {
  return true;
}

// 正确推断为 string | null
export const stringOrNull = createUnion([createString, createNull]);

// 正确推断为 number | undefined
export const numberOrUndefined = createUnion([createNumber, createUndefined]);

// 正确推断为 string | number,无类型报错
export const stringOrNumber = createUnion([createString, createNumber]);

// 正确推断为 number | string,无类型报错
export const numberOrString = createUnion([createNumber, createString]);

// 正确推断为 number | boolean,无类型报错
export const numberOrBoolean = createUnion([createBoolean, createNumber]);

内容的提问来源于stack exchange,提问作者David Y. Stephenson

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.22 03:43:15