Object is of type 'unknown' Error in TypeScript

avatar

Borislav Hadzhiev

Last updated: Jul 25, 2022

banner

Photo from Unsplash

Object is of type 'unknown' Error in TypeScript #

The "Object is of type unknown" error occurs when we try to access a property on a value that has a type of unknown. To solve the error, use a type guard to narrow down the type of the object before accessing a property, e.g. if (err instanceof Error) {}.

object is of type unknown

Here is an example of how the error occurs:

index.ts
async function fetchData() { try { await Promise.resolve(42); } catch (err) { // 👈️ err is type unknown // ⛔️ Error: object is of type unknown console.log(err.message); } }

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.

To get around this, we have to use a type guard to narrow down the type of the object before accessing a specific property.

index.ts
async function fetchData() { try { await Promise.resolve(42); } catch (err) { if (err instanceof Error) { // ✅ TypeScript knows err is Error console.log(err.message); } else { console.log('Unexpected error', err); } } }

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

If it is, we can safely access the message property, because all Error instances have a message of type string.

If you got the error in another place, you might not be providing a type for a generic, e.g. you might not be passing a type for the return value of an HTTP request.

With the unknown type, we first have to check the type that's currently stored in the variable before we get TypeScript support.

The type is used when there's no way to know what the variable stores in advance. Therefore before accessing a specific property or a method, we have to use a type guard.

index.ts
const something: unknown = 42; if (typeof something === 'string') { console.log(something.toUpperCase()); } else if (typeof something === 'number') { console.log(something.toFixed(2)); }

For example, you could check for the value's type to be able to use built-in methods.

index.ts
async function fetchData() { try { await Promise.resolve(42) } catch (err) { // 👈️ err is unknown if (typeof err === 'object' && err !== null) { console.log(err.toString()); } else { console.log('Unexpected error', err); } } }

We check if err has a type of object and is not null.

The null check seems kind of random, but we have to do it because null has a type of object in JavaScript (and TypeScript).

index.ts
console.log(typeof null); // 👉️ "object"
If err stores an object and is not null, we can safely use object-specific built-in methods, e.g. toString().

TypeScript didn't always type the error in the catch block as unknown. If you don't like this behavior, you can set the useUnknownInCatchVariables property to false in your tsconfig.json file to have the error typed as any.

tsconfig.json
{ "compilerOptions": { // ... other stuff "useUnknownInCatchVariables": false } }

If you set useUnknownInCatchVariables to false in your tsconfig.json file, the error variable will be typed as any.

index.ts
async function fetchData() { try { throw new Error('Something went wrong'); } catch (err) { // 👉️ err is type any console.log(err.message); // ✅ OK console.log(err.anything); // ✅ OK } }

However, when using this approach you might get unexpected runtime errors, because there's no way to be certain that what's being thrown is an Error instance (especially when using 3rd party packages).

Conclusion #

The "Object is of type unknown" error occurs when we try to access a property on a value that has a type of unknown. To solve the error, use a type guard to narrow down the type of the object before accessing a property, e.g. if (err instanceof Error) {}.

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.