Home > Blockchain >  typescript infer never[] when returned empty array from catch statement with async/await method
typescript infer never[] when returned empty array from catch statement with async/await method

Time:08-16

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[];
});
  • Related