In order to address the query at hand, let's take a step back and examine it from a broader perspective.
When it comes to TypeScript, both tuples and arrays share the same syntax (i.e., []
). However, they represent slightly different concepts. For the sake of brevity, I will denote tuples using ()
instead of TypeScript's standard []
in the subsequent paragraphs. It's important to note that in TypeScript T[] === Array<T>
.
Tuples are conventionally fixed-length and heterogeneous, meaning they can hold values of different types. For example, (1, "Adam", 42)
is a tuple of type (number, string, number)
.
On the other hand, arrays are typically homogeneous, containing elements of the same type, and can vary in length.
In TypeScript, the distinction between tuples and arrays becomes somewhat blurred due to support for union types. For instance, [1, "Adam", 42]
could also be considered a valid Array<T>
when T = number | string
. This flexibility is not achievable in languages lacking union types support, as it would result in determining the lowest-upper bound of number | string
, often leading to something like any
.
With this understanding, consider the following example snippet:
type Inferred<T> = T extends (...args: (infer UnionType)[]) => any ? UnionType : never
This piece of code essentially aims to extract the type T
from a function with arguments represented as an Array<T>
.
Given the argument list type of:
function f(first: 'first', second: 'second', bool: boolean)
We should be able to unify the following equations:
('first', 'second', boolean) :=: Array<T>
to ensure seamless interchangeability between values of type Array<T>
and ('first', 'second', boolean)
. However, since there's no suitable candidate for T, the inference results in never
.
While it might appear that T = string | boolean
or T = 'first' | 'second' | boolean
could serve as solutions, the subsequent illustration demonstrates otherwise:
type Arr = Array<'first' | 'second' | boolean>
type Tuple = ['first', 'second', boolean]
const a: Arr = ['first', 'second', true]
const t: Tuple = ['first', 'second', true]
let a1: Arr = t;
let t1: Tuple = a; // Type error no. 2322
Target requires 3 element(s) but source may have fewer.(2322)
On a type-level analysis:
type TEA = Tuple extends Arr ? true : false // true
type AET = Arr extends Tuple ? true : false // false
Furthermore, elucidating why
type Y = Inferred<(a: number, b: number, c: number) => void>
yields
number
.
To conclude, the use of (infer UnionType)[]
in your scenario appears to only facilitate array inference rather than tuple inference.
Please note that this explanation is based on general knowledge and intuition, as I do not possess specific insights into TypeScript compiler internals.