method getData() returns Promise<Output[]>
without catch statement type of data inferred is Output[]
but when I try to put catch statement in front of getData() method type of data becomes Output[] | void
and I can understand that if there is an error while getting data then I am not returning anything from catch block.
When I try to return an empty array from catch statement type of data that typescript is inferring is Output[] | never[]
. I am not able to understand the concept of never[]
I am not able to grasp the concept of never[]. and what would be the best practice/solution in this case to handle error and get the intended type of array instead of void
or never
.
const data = await getData().catch((e) => {
handleError(e);
return [];
});
CodePudding user response:
when you're using async/await, the general approach is to wrap it with try/catch. This helps with typescript inferring the type.
For example,
async function getData() {
return [1];
}
// inferred as `number[] | never[]` because .catch adds additional types.
// The returned value could be the type from getData or the type from the catch function.
// Promise<number[]>.catch<never[]>
const data = await getData().catch(e => {
...
})
Whereas if you wrap it with try/catch
try {
// inferred as `number[]`
const data = await getData();
return data;
} catch (e) {
handleError(e);
return [];
}
Here is a full example.
async function getData() {
return [1];
}
function handleError(e: any) {
console.log(e);
}
async function main() {
try {
const data = await getData();
return data;
} catch (e) {
handleError(e);
return [];
}
}
main();
CodePudding user response:
When you return []
, TS assumes that it'll always be an empty array. It's a tuple type with 0 elements. That's why you get a never[]
. Since you'll never be able to access any of its elements.
You can change it to:
const data = await getData().catch((e) => {
handleError(e);
return [] as Output[];
});