What is the reason that TS does not allow for returning empty array from generic function even if this generic parameter extends (has constrain) array? Result should derive from an array.
Below code:
// it does not work
async function handleErrors<Result extends Array<any>>(asyncCall: () => Promise<Result>): Promise<Result> {
try {
return await asyncCall();
} catch (e) {
return [];
// return [] as Result; // also does not work - needed casting to `any`/`unknown` first
}
}
Error:
Type 'never[]' is not assignable to type 'Result'.
'never[]' is assignable to the constraint of type 'Result', but 'Result' could be instantiated with a different subtype of constraint 'any[]'.(2322)
OR if casting applied
Conversion of type 'never[]' to type 'Result' may be a mistake because neither type sufficiently overlaps with the other. If this was intentional, convert the expression to 'unknown' first.
'never[]' is assignable to the constraint of type 'Result', but 'Result' could be instantiated with a different subtype of constraint 'any[]'.(2352)
Type of []
is never[]
.
I understand that I cannot return an array with elements from this function because exact type will be inferred from the usage (which is not yet known, in function definition). It can be an array of numbers, strings, etc. so I cannot return e.g. the array of objects. But why returning empty array does not work?
Is the reason that return type can be some type which derives from the array? So just empty array will not have some properties from this type inferred from the usage?
If I use single element as generic parameter then everything works correctly:
async function handleErrors<Element>(asyncCall: () => Promise<Element[]>): Promise<Element[]> {
try {
return await asyncCall();
} catch (e) {
return [];
}
}
Both versions with example of the usage: TS playground