Reputation: 79
I've got an array of the following types:
myList = [
listOfString: Parser<string[], string, any>
stringThing: Parser<string, string, any>
]
and typesript marks myList of type (Parser<string[], string, any> | Parser<string, string, any>)[]
Is there a way to convert this into Parser<string | string[], string, any>
by default?
Alternativly, when passing this to a function that looks like
myFunc<T>(list: Parser<T>[]): Parser<T>
is there a way to allow this type of array and make it that myFunc
returns Parser<string | string[], string, any>
?
Upvotes: 0
Views: 262
Reputation: 20033
Is there a way to convert this into
Parser<string | string[], string, any>
[...]?
T<string> | T<string[]>
and T<string | string[]>
are not equivalent types in the general case.
Consider as an example
type T<U> = (u: U) => U;
Now T<string> | T<string[]>
is either a function taking a string, or a function taking an array of strings. In either case the function's parameter is only one of those two types, and you can only call it with an argument of that type. If you (can) call it with a string, you can't call it with an array of strings, and it must also return a string.
On the other hand, T<string | string[]>
describes a function whose parameter is a string or an array of strings, meaning that for every single invocation you can choose which one you pass. It would also be possible that you call it with a string but the function returns an array of strings.
With a concrete example, (u: string) => u
would satisfy the first type, but isn't assignable to the second:
// OK
const test1: T<string> | T<string[]> = (u: string) => u;
// Error
const test2: T<string | string[]> = (u: string) => u;
Similarly, (u: string | string[]) => u
has the opposite effect:
// Error
const test3: T<string> | T<string[]> = (u: string | string[]) => u;
// OK
const test4: T<string | string[]> = (u: string | string[]) => u;
Upvotes: 3