Catch clause variable type annotation must be any or unknown if specified

avatar
Borislav Hadzhiev

Last updated: Feb 28, 2024
3 min

banner

# Catch clause variable type annotation must be any or unknown if specified

The error "Catch clause variable type annotation must be 'any' or 'unknown'" occurs when we try to type the error variable in a catch block.

To solve the error, remove the typing and use a type guard to check if the error is of a specific type, e.g. if (err instanceof Error){}.

Here is an example of how the error occurs.

index.ts
async function getNumber() { try { const result = await Promise.resolve(42); return result; // โ›”๏ธ Error: Catch clause variable type annotation must be 'any' or 'unknown' if specified.ts(1196) } catch (err: Error) { console.log(err.message); } }

catch clause variable type annotation must be any or unknown

We cannot guarantee that the error in the catch block will be an Error instance ahead of time, so TypeScript sets its type to unknown to avoid any unexpected runtime errors.

# Use a type guard to solve the error

We have to use a type guard to narrow down the type of the object before accessing a specific property.

index.ts
async function getNumber() { try { const result = await Promise.resolve(42); return result; } catch (err) { if (err instanceof Error) { // ๐Ÿ‘‰๏ธ err is type Error here console.log(err.message); return; } console.log('Unexpected error', err); return; } }

use type guard to solve the error

The code for this article is available on GitHub

We used the instanceof operator to check if err is an instance of the Error object.

You could use this approach to check if the error variable in the catch block is an instance of any specific Error class, even if you have CustomError classes.

It is only safe to access the message property once we've narrowed down the type in the if block, otherwise, the type of the err variable is unknown.

# Using a type assertion to solve the error

If this approach doesn't work for you and you need to type the error variable in the catch block, you can use a type assertion.

index.ts
async function getNumber() { try { const result = await Promise.resolve(42); return result; } catch (err) { const typedError = err as Error; console.log(typedError?.message); return; } }

using type assertion to solve the error

The code for this article is available on GitHub

We explicitly typed the err variable in the catch block, even though there is no way to guarantee that all caught errors will be of the specific type.

# Solve the error when using axios

If you use the axios package and need to type the error in the catch block as an AxiosError, use the isAxiosError() helper function.

index.ts
import axios from 'axios'; async function getData() { try { // ๐Ÿ‘‰๏ธ ... fetch data here return 'hello'; } catch (error) { if (axios.isAxiosError(error)) { console.log('error message: ', error.message); // ๐Ÿ‘‡๏ธ error: AxiosError<any, any> return error.message; } else { console.log('unexpected error: ', error); return 'An unexpected error occurred'; } } }
The code for this article is available on GitHub

The isAxiosError function is used as a type guard.

In the if block we can access all of the properties an AxiosError has, e.g. config, code, request and response.

I've also written a detailed guide on how to make HTTP requests with Axios in TypeScript.

If you'd rather use the built-in fetch module, check out the following article instead.

# Additional Resources

You can learn more about the related topics by checking out the following tutorials:

I wrote a book in which I share everything I know about how to become a better, more efficient programmer.
book cover
You can use the search field on my Home Page to filter through all of my articles.

Copyright ยฉ 2024 Borislav Hadzhiev