Issue
I want to have a conditional type, that is a "partially" distributive conditional type. More specifically I want to treat undefined separately regarding the distributive behavior. Is this possible?
type ToArray<Type> = [Type] extends [any] ? Type[] : never
type ToArrayOrUndefined<T> = T extends undefined ? undefined : ToArray<T>
type Test1 = ToArray<string | number> //=> (string | number)[] (OK)
type Test2 = ToArray<string | number | undefined> // => (string | number | undefined)[] (OK)
type Test3 = ToArrayOrUndefined<string | number | undefined> // number[] | string[] | undefined, but should be (string | number)[] | undefined
type Test4 = ToArrayOrUndefined<string | number> // number[] | string[], but should be (string | number)[]
Solution
This code does the trick, where the essential difference with your code is that undefined
is a sub-type of a union containing undefined
, not the other way round:
type ToArray<T> = [T] extends [any] ? T[] : never;
type ToArrayOrUndefined<T> = [undefined] extends [T]
? ToArray<Exclude<T, undefined>> | undefined
: ToArray<T>;
type Test1 = ToArray<string | number>
// => (string | number)[]
type Test2 = ToArray<string | number | undefined>
// => (string | number | undefined)[]
type Test3 = ToArrayOrUndefined<string | number | undefined>
// => (string | number)[] | undefined
type Test4 = ToArrayOrUndefined<string | number>
// => (string | number)[]
(Though, I can hardly see the point of such an approach: how is that better than directly a type Test3 = ToArray<string | number> | undefined
? Moreover, consider a type Test5 = ToArray<string | number | undefined> | undefined
, and there is no way to rewrite that as a ToArrayOrUndefined
, so that ToArrayOrUndefined
is not even very general.)
Answered By - Julio Di Egidio
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.