Let's say I have a type which is a union of literals:
type X = "a" | "b" | "c";
Now I want to introduce a new type signifying a union of arrays of each type in X. In other words, I want to apply the array operator distributively over the union.
Just adding the array operator on the type doesn't do what I want – this will permit a mixed array e.g.
type Y = X[]; // ("a" | "b" | "c")[]
const xs: Y = ["a", "b"]; // valid
However, conditional types have the distributive property that I seek. I seem to be able to achieve my goal by using them in conjunction with a condition that never gets fulfilled:
type Arrayify<T> = T extends never ? never : T[];
type Y = Arrayify<X>; // "a"[] | "b"[] | "c"[]
const xs: Y = ["a", "b"]; // invalid
As far as I can tell it solves my problem, but it feels a little backwards to take the detour through conditional types only to get the distributivity. Is there a better, more conventional way?