Even in normal lodash
, zip's type is declared using overloads, like:
zip<A, B>(a1: A[], a2: B[]): Array<[A, B]>;
zip<A, B, C>(a1: A[], a2: B[], a3: C[]): Array<[A, B, C]>;
zip<A, B, C, D>(a1: A[], a2: B[], a3: C[], a4: D[]): Array<[A, B, C, D]>;
zip<A, B, C, D, E>(a1: A[], a2: B[], a3: C[], a4: D[], a5: E[]): Array<[A, B, C, D, E]>;
The first line of this satisfies zip
from lodash/fp
, but what about zipAll
?
This function is supposed to take a second order array and basically transpose it.
It would look like this for the above limited cases:
zipAll<A, B>([A[], B[]]): Array<[A, B]>;
zipAll<A, B, C>([A[], B[], C[]]): Array<[A, B, C]>;
zipAll<A, B, C, D>([A[], B[], C[], D[]]): Array<[A, B, C, D]>;
zipAll<A, B, C, D, E>([A[], B[], C[], D[], E[]]): Array<[A, B, C, D, E]>;
Is there no way to define it generally?
This isn't much of an answer, but: no there isn't. This would require some sort of meta-programming layer.
You can see very similar patterns applied in other languages, for example Haskell. Even though Haskell's type system can be considered more sophisticated, it doesn't have overloads, and zip
is implemented for different sized tuples using new names: zip
, zip3
, zip4
etc. In general, Haskell's Prelude stops at 7 arguments when defining these types of thing, since the code generally becomes unreadable by that point anyway.