如何测试一个元组是有限的还是无限的?
这是目前为止我所拥有的,但它不适用于最后一种情况:
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链接到代码