15 день, 15 задача.
В данной задаче нам нужно на основании объединения с некими числами создать объединение с массивами, длина которых будет равна этим числам и заполнить каждый из них определенным словом. Мы столкнемся с рекурсивными типами и дистрибутивностью объединений.
Для начала создадим вспомогательный тип который будет создавать кортеж с заданной длиной и наполнять его переданным элементом:
type CreateTupleWith<E, L extends number, _Acc extends E[] = []> =
_Acc['length'] extends L ? _Acc : CreateTupleWith<E, L, [..._Acc, E]>
Создаем 3 generic - элемент, которым будем заполнять кортеж, число, которое будет ограничивать его длину, и аккумулятор который будет хранить промежуточный результат. Как и в любом рекурсивном типе, ставим условие для выхода - если длина аккумулятора равна переданному числу - вернем аккумулятор, в противном случае мы снова вызовем тип, добавив в промежуточный результат еще один элемент.
Теперь нам нужно разобраться, как создать несколько таких кортежей и засунуть в объединение.
Вот полное решение:
type CreateTupleWith<E, L extends number, _Acc extends E[] = []> =
_Acc['length'] extends L ? _Acc : CreateTupleWith<E, L, [..._Acc, E]>
type BoxToys<T, C extends number> =
C extends C ? CreateTupleWith<T, C> : never;
Тип
BoxToys
принимает на вход элемент, которым нужно заполнить кортежи, и объединение чисел, обозначающее их длину.
Используя дистрибутивность, мы можем "перебрать" наше объединение. Вот небольшой пример для понимания "C extends C":
type Hey<T extends string> = T extends T ? `${T}_lol` : never;
// "typescript_lol" | "is_lol" | "awesome_lol"
type Test = Hey<'typescript' | 'is' | 'awesome'>
Если мы начинаем использовать
extends
с объединением, то оно становится дистрибутивным, то есть каждый его элемент проходит проверку через
extends
. Получается, мы проверяем, каждый ли элемент объединения является подтипом каждого элемента его же самого, таким образом создавая перебор по всем элементам.
В нашем же случае
BoxToys
перебирает переданное объединение и на основании каждого его участника создает кортеж, которые впоследствие так же схлопываются в юнион.