Reputation: 3146
I have an array of type MyArray.
type Maybe<T> = T | null;
type MyArray = Maybe<Materials>[] | Maybe<Seasons>[] | Seasons[] | Materials[] | null | undefined;
type Value = Seasons | Materials;
Example code:
if (!myArray?.length) {
return;
}
const isValid = myArray.includes(value); // typescript is complaining about value
The issue is when I highlight value:
Argument of type Seasons | Materials is not assignable to parameter of type 'never'.
How can I get rid of this error?
Upvotes: 0
Views: 1011
Reputation: 791
This error is actually legit, there is a mismatch because:
Seasons | Materials
(the value)Seasons[]
that won't accept the value because it could be a Materials
Materials[]
that won't accept the value either because it could be a Seasons
We can try to fix it by using an intermediate includes
function, such as:
type ElementOf<A extends any[], B> = B extends A[number] ? B : never
function includes<A extends any[], B>(list: A, element: ElementOf<A, B>): boolean {
return list.includes(element)
}
This function ensures that:
Seasons[]
, or a box of Materials[]
, but not a box of (Seasons | Materials)[]
const isValid = includes(myArray, value)
You can check on this playground.
Previous answer:
I'm pretty sure we can fix this issue by simplifying the definition of the MyArray
type:
type MyArray = Maybe<Array<Maybe<Materials> | Maybe<Seasons>>> | undefined
// or: type MyArray = Array<Maybe<Materials> | Maybe<Seasons>> | null | undefined
function foo(myArray: MyArray, value: Value): void {
// myArray: Maybe<Array<Value | null>> | undefined (or, equivalent -> myArray: Array<Value | null> | null | undefined)
if (!myArray?.length) {
return
}
// myArray: Array<Value | null>
const isValid = myArray.includes(value)
console.log(isValid)
}
Somehow, when the type of myArray
is a union type of arrays:
type MyArray =
| Maybe<Materials>[]
| Maybe<Seasons>[]
| null
| undefined
Instead of an array of a union type:
type MyArray = Array<Maybe<Materials> | Maybe<Seasons>> | null | undefined
Then the type inference when using the includes
function is broken, so we end up with the type never
instead of Maybe<Value>
(or Value | null
, same thing).
I don't know if this behavior is intended or a bug, it might be interesting to look for an open issue on the TypeScript repository mentioning this, or create a new one.
Upvotes: 2