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

如何检测TypeScript元组为有限或无限?

如何检测TypeScript元组是有限还是无限?

我需要实现一个类型工具IsFinite来判断元组是有限还是无限,但当前实现无法处理包含多个rest元素的复杂元组,比如[string, ...[string, number], ...string[], string]会返回never,而非正确的false。

原实现代码

type IsFinite<T extends any[], Finite = true, Infinite = false> = T extends []
  ? Finite
  : T extends (infer Element)[]
  ? Element[] extends T
    ? Infinite
    : T extends [any, ...infer Rest]
    ? IsFinite<Rest, Finite, Infinite>
    : never
  : never

type Foo1 = IsFinite<[string]>                          // true
type Foo2 = IsFinite<[]>                                // true
type Foo3 = IsFinite<string[]>                          // false
type Foo4 = IsFinite<[arg1: string, ...args: string[]]> // false

type Foo5 = IsFinite<[string, ...[string, number], ...string[], string]> // never <- 无法处理该情况

问题分析

原实现通过递归拆解元组判断有限性,但当元组包含多个rest扩展(比如嵌套的...[string, number]和...string[])时,T extends [any, ...infer Rest]无法匹配这种复杂结构,导致走到never分支。实际上只要元组中存在任意一个无限rest元素(即数组类型而非有限元组),整个元组就是无限的。

解决方案

换个思路:只要元组无法被递归拆解为首元素加剩余元组,就说明它包含无限rest,属于无限元组。以下是修正后的实现:

type IsFinite<T extends any[], Finite = true, Infinite = false> = 
  T extends [] ? Finite :
  T extends [infer _, ...infer R] ? IsFinite<R, Finite, Infinite> :
  Infinite;

测试验证

type Foo1 = IsFinite<[string]>                          // true
type Foo2 = IsFinite<[]>                                // true
type Foo3 = IsFinite<string[]>                          // false
type Foo4 = IsFinite<[arg1: string, ...args: string[]]> // false
type Foo5 = IsFinite<[string, ...[string, number], ...string[], string]> // false <- 现在正确返回无限

逻辑说明

  • 空元组直接判定为有限(Finite)
  • 能拆解为首元素加剩余元组的,递归判断剩余部分
  • 无法拆解的元组(包含无限rest)直接判定为无限(Infinite)

这种实现可以处理任意位置、任意数量的rest元素,覆盖所有复杂元组场景。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 12:07:35