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:
ts
try {// some code} catch (e ) {'e' is of type 'unknown'.18046'e' is of type 'unknown'.console .log (); e .message }
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:
ts
try {// some code} catch (e ) {if (typeofe === "object" &&e &&"message" ine &&typeofe .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
!
instanceof
Solution 2: Narrow the type using If you're dealing with a class, you can use instanceof
to narrow the type. This works especially well with errors:
ts
try {// some code} catch (e ) {if (e instanceofError ) {// 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:
ts
functionhasMessage (x : unknown):x is {message : string } {returnBoolean (typeofx === "object" &&x &&"message" inx &&typeofx .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:
ts
try {// some code} catch (e ) {console .log ((e asError ).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!
Share this TypeScript Concept with your friends