Home > OS >  How to narrow down types for TS2339: Property 'data' does not exist on type 'Error |
How to narrow down types for TS2339: Property 'data' does not exist on type 'Error |

Time:10-16

I have an arrow function:

const getCsrfToken = async () => {
  const csrfTokenResponse = await axios.get<any, AxiosResponse<CSRFToken>>(csrfUrl);
  if (csrfTokenResponse?.data) {
    return csrfTokenResponse.data;
  }
  return Error('Failed to fetch CSRF token.');
};

TypeScript gives this warning:

TS2339: Property 'data' does not exist on type 'Error | CSRFToken'.
Property 'data' does not exist on type 'Error'.

If axios returns a response, it will be of type CSRFToken, which definitely has a data property.

So, I thought using the ? in csrfTokenResponse?.data would be sufficient to guarantee that axios returned CSRFToken and not Error, but TypeScript is still giving me this message.

How can I fix the TypeScript warning?

TypeScript 4.4

CodePudding user response:

there are multiple ways you can go through fixing this error.

casting

you can cast the return value if you're sure the return value is defined.

(csrfTokenResponse as CSRFToken).data

type check before accessing

you can use the following utility type to assert if the returned value is an error

const isError = (err: unknown): err is Error => err instanceof Error;

throw error instead of returning it.

you can keep a consistent return type by using throw Error instead of returning it.

A better return format

the following return format is inspired by how go handles return values.

const getCsrfToken = async () => {
  const csrfTokenResponse = await axios.get<any, AxiosResponse<CSRFToken>>(csrfUrl);
  if (csrfTokenResponse?.data) {
    return [data, null] as const;
  }
  return [null, Error('Failed to fetch CSRF token.')] ;
};

and use it like this

const [data, error] = await csrfTokenResponse()
  • Related