# Flatten Tuple Type

1type Flatten<T> = any; // implementation23type Step1 = Flatten<[1, [2, [3, [4]]]]>;4type Step2 = [1, ...Flatten<[2, [3, [4]]]>];5type Step3 = [1, 2, ...Flatten<[3, [4]]>];6type Step4 = [1, 2, 3, ...Flatten<[4]>];7type Result = [1, 2, 3, 4];

Today we discuss Flatten

It works the same way as Array.prototype.flat when you pass `Infinity`

Let's find out how to do that in TypeScript 💪

## Iteration over tuple elements

Knowing the approach from different challenges, as we want to save the structure (it will be tuple at the end), we apply Type inference in conditional types with Rest elements in Tuples.

We iterate over elements:

1type Flatten<T> = T extends []2 ? []3 : T extends [infer Head, ...infer Tail]4 ? [] // make it flatten using Head and Tail5 : [];

Then we have 2 cases:

- If the element is a tuple, we apply changes recursively
- Otherwise, we leave it as is

Let's add second case:

1type Flatten<T> = T extends []2 ? []3 : T extends [infer Head, ...infer Tail]4 ? [Head, ...Flatten<Tail>]5 : [];

## Call it recursively when needed

At the moment, if we have a look at Playground – https://tsplay.dev/w18bXW, we will find that not all tests are passed.

We forgot to apply function recursively when we have an element as tuple. Let's have an example here:

1type Step1 = Flatten<[1, [2]]>;2type Step2 = [1, ...Flatten<[[2]]>];3// ❌ Expected to have [1, 2] instead4type Result = [1, [2]];

In this case we cannot just add it to result tuple, we need to call `Flatten`

before and then put all the elements of it to the result type. Let's change the implementation based on that:

1type Flatten<T> = T extends []2 ? []3 : T extends [infer Head, ...infer Tail]4 ? Head extends any[]5 ? [...Flatten<Head>, ...Flatten<Tail>]6 : [Head, ...Flatten<Tail>]7 : [];

Now it's working as expected 🔥

Check out Playground – https://tsplay.dev/WKk0DW

And last but not least, as you see we return empty array `[]`

in several places, let's simplify solution a little bit:

1type Flatten<T> = T extends [infer Head, ...infer Tail]2 ? Head extends any[]3 ? [...Flatten<Head>, ...Flatten<Tail>]4 : [Head, ...Flatten<Tail>]5 : [];

Shorter solution – https://tsplay.dev/WP7gzm

Thank you for your time and have a productive upcoming week 🚀

typescript