I have zip and unzip functions like this:
function range(size: number, startAt: number = 0): ReadonlyArray<number> {
return [...Array(size).keys()].map((i) => i + startAt);
}
function unzip<T extends unknown[]>(array: T[]) /* ??? */ {
const maxLength = Math.max(...array.map((x) => x.length));
return array.reduce(
(acc, val) => {
val.forEach((v, i) => acc[i].push(v));
return acc;
},
range(maxLength).map(() => [])
);
}
function zip<T extends unknown[]>(...arrays: T[]) /* ??? */ {
const maxLength = Math.max(...arrays.map((x) => x.length));
return range(maxLength).map((i) =>
range(arrays.length).map((_, k) => arrays[k][i])
);
}
I have no idea how to type the return types though. Is it even possible?
I think it would be nice if zip([1, 2, 3], ["a", "b"]) returned with a type of [number | undefined, string | undefined][]. It seems that there is an answer here as someone in the comments pointed out that does precisely this. Likewise, it would be nice if unzip([1, "a"], [2, "b"], [3, undefined]) returned a type of [number[], string[]] or maybe [number[], (string | undefined)[]] depending on whichever is easiest.
I am a typescript noob, so naturally I tried to find some types on the internet, but they all seem to go the "lazy" route and type returns as any.
If this is even possible, how would I type the return types of these two functions (as well as similar functions where you "invert" the type of an array)?
zip([1,2,3],["a", "b"])could produce a value of type anywhere from the loose(number | string)[][]to the more reasonable[number | undefined, string | undefined][]to the incredibly specific[[1, "a"],[2, "b"],[3, undefined]]. Without more clarity in the question, this could have many possible answers.zipfunction return type: stackoverflow.com/a/70192772/8613630