type ToArray<T> = T extends any ? T[] : never;
type R = ToArray<string | number>;
string[] | number[]The answer is string[] | number[]. Here T is a naked type parameter: it stands alone in the check (T extends ...), not wrapped in something like [T]. A conditional type on a naked type parameter is distributive. This means it runs once for each union member and then joins the results into a union.
So ToArray<string | number> becomes ToArray<string> | ToArray<number>, which is string[] | number[].(string | number)[] is the tempting wrong answer. To get it, wrap both sides in a tuple so the type is no longer naked: [T] extends [any] ? T[] : never.
Read more