Проблема

Реализовать тип First<T>, который принимает на входе массив T и возвращает тип его первого элемента. Например:

type arr1 = ["a", "b", "c"];
type arr2 = [3, 2, 1];

type head1 = First<arr1>; // expected to be 'a'
type head2 = First<arr2>; // expected to be 3

Решение

Первая мысль, которая меня посетила, это использовать типы поиска и написать T[0]:

type First<T extends any[]> = T[0];

Но это решение не учитывает один случай. Если мы передадим пустой массив, то у него не будет элемента по индексу 0. А значит, не будет и типа, который нам нужен.

Поэтому, прежде чем обращаться к первому элементу из массива, давайте проверим, а не пустой ли массив. Чтобы это сделать, мы можем использовать условные типы.

В случае, если T (входной массив) можно присвоить к пустому массиву, это значит что массив пустой. В таком случае, мы возвращаем never. Нет элемента - нет типа.

Но, если мы не можем присвоить T к пустому массиву, значит массив не пустой и можем спокойно возвращать T[0].

type First<T extends any[]> = T extends [] ? never : T[0];

Что почитать