Given the following code
type Test = string | boolean | string[] | boolean[]
function test (param: Test) {
if (!_.isArray(param)) {
param = [param]
}
return param
}
I recieve the following error
(parameter) param: string | boolean Type 'string | boolean' is not assignable to type 'boolean'. Type 'string' is not assignable to type 'boolean'.ts(2322)
The solution is
type Test = string | boolean | (string | boolean)[]
But I don't understand my solution 😅
To put it into words I have a type which consists of two arbitrary types and (bad I know) arrays of those types. Through (!_.isArray) type guarding I (bad I know) mutate the parameter.
Inside the type guard my type definition is narrowed to 'string | boolean'. Typescript is telling me I can't assign the value I want to this type.
Please give me insight into understanding the error and solution.
Thank you
The issue here is that once you establish that param
isn't an array, it's type is constrained to string | boolean
, when you take a value of that type and put it in an array literal Typescript infers the type to be [string | boolean]
which is different than string[] | boolean[]
. If you instead checked for each possible type and then had the same line of code in a separate branch that would work:
type Test = string | boolean | string[] | boolean[]
function test(param: Test) {
if (typeof param === 'string') {
param = [param];
} else if (typeof param === 'boolean') {
param = [param];
}
return param
}
In case it isn't clear the difference between these types is that one ((string | boolean)[]
) can be an array containing a mix of strings and booleans, where as the other (string[] | boolean[]
) is either an array of only strings, or an array of only boolean. Unfortunately Typescript isn't smart enough in this case to realize that the array [param]
is inherently homogenous because it has only a single element.