3

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?

1 Answer 1

3

Your approach is the right one. Using conditional types for distribution is the way to accomplish this. The recommended patterns to get just the distributive behavior is T extends T or T extends unknown, but yours works just fine as well in this case.

type Arrayify<T> = T extends T ? T[] : never;
Sign up to request clarification or add additional context in comments.

2 Comments

I just realised there's a small complication applying this approach to booleans, since they are defined as true | false unions. Thus, Arrayify<boolean> will result in true[] | false[] and not boolean[]. Is there any way of "blocking" the distributivity?
@HannesPetri the usual way to block distributivity is to use a tuple. This should work : type Arrayify<T> = [T] extends [boolean] ? T[] : T extends T ? T[] : never; although you will still get strange distribution over enums.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.