Quick Explanation
Object is of type 'unknown'.
This error is probably occurring because you're trying to access a property on something marked as unknown
before narrowing it. You should either narrow it, or use a type assertion.
This is extremely common in try
/catch
blocks:
try {
// some code
} catch (e ) {
console .log (e .message );'e' is of type 'unknown'.18046'e' is of type 'unknown'.}
This is happening because unknown
is considered to be any possible type. It's different from any
because you can't access any properties on it without narrowing it first. With any
, you can access any property on it without narrowing it.
Solution 1: Narrow the type
The first option is to narrow the type. You can do this by checking if the property exists on the object:
try {
// some code
} catch (e ) {
if (
typeof e === "object" &&
e &&
"message" in e &&
typeof e .message === "string"
) {
// message gets narrowed to string!
console .log (e .message ); }
}
We first check if e
is an object
. Then, we check if it's not null
or undefined
. Then, we check if it has a message
property. Finally, we check if e.message
is a string
.
TypeScript is smart enough to follow along with this logic and narrow e.message
to a string
!
Solution 2: Narrow the type using instanceof
If you're dealing with a class, you can use instanceof
to narrow the type. This works especially well with errors:
try {
// some code
} catch (e ) {
if (e instanceof Error ) {
// e is narrowed to Error!
console .log (e .message ); }
}
Solution 3: Use a type predicate
You can wrap your narrowing logic in a custom type predicate:
function hasMessage (x : unknown): x is { message : string } {
return Boolean (
typeof x === "object" &&
x &&
"message" in x &&
typeof x .message === "string"
);
}
try {
// some code
} catch (e ) {
if (hasMessage (e )) {
// e is narrowed to { message: string }!
console .log (e .message ); }
}
This is useful if you want to reuse the same logic in multiple places.
Solution 4: Use a type assertion
If you're sure that the type is correct, you can use a type assertion to tell TypeScript that it's correct:
try {
// some code
} catch (e ) {
console .log ((e as Error ).message );
}
This is the least type-safe option, but it's also the easiest to use. Just be careful that you're not asserting the wrong type!
Object is of type 'unknown'