如何测试一个元组是无限的还是有限的?



如何测试一个元组是有限的还是无限的?

这是目前为止我所拥有的,但它不适用于最后一种情况:

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 <- doesn't handle this case

代码

我认为是一个"无穷大"数组/元组你指的是没有已知length上界的数组类型;在TypeScript中,这意味着一个数组类型的length属性是number,而不是"有限"数组/元组,其length属性是某种数字文字类型或这些文字的并集:

type Length<T extends any[]> = T['length'];
type L1 = Length<[string]>                          // 1
type L2 = Length<[]>                                // 0
type L3 = Length<string[]>                          // number
type L4 = Length<[arg1: string, ...args: string[]]> // number
type L5 = Length<[string, ...[string, number], ...string[], string]> // number
type L6 = Length<[string, string?]> //  1 | 2

所以你可以将IsFinite<T>定义为检查length属性类型的条件类型:

type IsFinite<T extends any[], F = true, I = false> =
number extends T['length'] ? I : F
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
type Foo6 = IsFinite<[string, string?]> //  true

Playground链接到代码

相关内容

最新更新