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

如何从剩余参数中推断联合类型?TypeScript泛型问题

解决TypeScript泛型剩余参数联合类型推断问题

问题背景

需要实现一个translate函数,要求:

  • 以剩余参数的联合类型作为泛型判断依据
  • 若剩余参数中存在至少一个非字符串/数字的元素,返回ReactNode | ReactNode[]
  • 若所有剩余参数都是字符串或数字,返回string

原代码如下:

type TTranslationResult<T> = T extends number | string
  ? string
  : ReactNode | ReactNode[];

export default function translate<T extends ReactNode = string>(
  key: TDictionaryKey,
  ...params: T[]
): TTranslationResult<T> {
  // 函数逻辑
}

当传入混合类型参数时:

translate(
   'XXX',
   'some string',
   <LinkText href={`foo`}>
       {foo}
   </LinkText>
)

期望泛型T被推断为string | ReactNode,但实际仅推断出第一个元素的string类型。

问题原因

  1. 原函数中...params: T[]的定义,会让TypeScript将T推断为所有参数的共同父类型,而非联合类型。如果第一个参数是string(且string属于ReactNode子类型),TypeScript会直接沿用默认泛型string或收窄到string,忽略后续的ReactNode类型参数。
  2. 原TTranslationResult的条件判断是分布式的,若T为联合类型,会对每个分支单独判断,导致返回不符合预期的联合类型。

解决方案

步骤1:修改类型判断逻辑

使用非分布式条件类型,判断剩余参数的联合类型是否全部为字符串/数字:

// 判断联合类型是否全为number或string(非分布式)
type AllStringOrNumber<T> = [T] extends [number | string] ? true : false;

type TTranslationResult<T> = AllStringOrNumber<T> extends true
  ? string
  : ReactNode | ReactNode[];

步骤2:调整泛型推断方式

将泛型改为捕获剩余参数的元组类型,再通过Params[number]提取元组元素的联合类型:

export default function translate<Params extends ReactNode[] = string[]>(
  key: TDictionaryKey,
  ...params: Params
): TTranslationResult<Params[number]> {
  // 函数逻辑
}

效果验证

传入混合类型参数时:

  • Params会被推断为[string, ReactNode]
  • Params[number]得到联合类型string | ReactNode
  • AllStringOrNumber<string | ReactNode>返回false,因此函数返回ReactNode | ReactNode[],符合需求

若传入全字符串/数字参数:

translate('YYY', 'hello', 123);
  • Params为[string, number]
  • Params[number]为string | number
  • AllStringOrNumber<string | number>返回true,函数返回string,符合需求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 20:58:10