Flatten
Проблема
Реализуйте тип, который принимает массив и возвращает его плоскую версию. Например:
type flatten = Flatten<[1, 2, [3, 4], [[[5]]]> // [1, 2, 3, 4, 5]
Решение
Начнем со случаев попроще. Когда получаем пустой массив, возвращаем пустой
массив, так как он и так плоский, с ним ничего не нужно делать. Иначе, вернём
сам T
(пока что):
type Flatten<T> = T extends [] ? [] : T;
Но, что если T
будет не пустым массивом? Это значит, что у нас массив с
элементами внутри или сам элемент из массива. Если работаем с массивом из
элементов, выводим один элемент из него и остальную часть. После вывода,
возвращаем новый массив, с выведенными элементами.
type Flatten<T> = T extends []
? []
: T extends [infer H, ...infer T]
? [H, T]
: [T];
Кстати, обратите внимание, что в случае, если у нас не пустой массив и не массив с элементами, то ожидаем что это элемент из массива. В таком случае, возвращаем этот элемент в кортеже.
Имея выведенные типы из массива, мы можем рекурсивно вызывать Flatten
снова и
снова и передавать в него эти выведенные типы. Таким образом, заходим вглубь
массива до тех пор, пока не дойдем до элемента. И как только получили этот
элемент, возвращаем его как базовый случай [T]
.
В результате, получаем тип, который рекурсивно обходит каждый элемент и возвращает вместо него кортеж из одного элемента. Благодаря вариативным типам, эти кортежи сливаются в один, который и даёт нам плоский массив.
type Flatten<T> = T extends []
? []
: T extends [infer H, ...infer T]
? [...Flatten<H>, ...Flatten<T>]
: [T];
Комментарии