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];
Коментарі