If you can get your multiple tuple fragments into array form, then you can also use a type like this for an arbitrary amount of tuple fragments:
type Flattened<Fragments extends any[][]> =
Fragments extends
[
infer CurrentTupleFragment extends any[],
...infer RemainingTupleFragments extends any[][]
] ?
[
...CurrentTupleFragment,
...Flattened<RemainingTupleFragments>
] :
[];
type flat = Flattened<[["a", "b"], ["c"], ["d", "e", "f"]>; //["a", "b", "c", "d", "e", "f"]
This works its magic by first recursively splitting the array into its front element CurrentTupleFragment and the remaining yet to be recursively treated elements until it hits the end of the array (the first extends clause does not match anymore) and then returning an empty array up the recursion chain.
When on the way back up, we then spread out the CurrentTupleFragment and effectively prepend them to the already spread out tuple fragments from our recursion, which we of course need to spread out again, otherwise we would get ever deeper nested Arrays (try removing the ... before the recursive Flatten to see what I mean).