How to fix Object is of type 'unknown' in TypeScript
This TypeScript error occurs when trying to access properties or methods on a value typed as `unknown` without first narrowing its type. It's most common in `try/catch` blocks where caught errors are `unknown` by default. The fix involves using type guards like `instanceof`, `typeof`, or type assertions to safely work with unknown values.
Quick fix
Fixes Object is of type 'unknown'
try {
// Some code that might throw
} catch (error) {
// TypeScript error: Object is of type 'unknown'
// console.log(error.message); // Error!
if (error instanceof Error) {
// Now TypeScript knows error is an Error
console.log(error.message); // Works!
}
}- Use instanceof for class-based type checking
- Use typeof for primitive type checking
- Create custom type guards for complex types
- Use type assertions when you're certain
try {// Some code that might throw} catch (error) {// TypeScript error: Object is of type 'unknown'// console.log(error.message); // Error!if (error instanceof Error) {// Now TypeScript knows error is an Errorconsole.log(error.message); // Works!}}Object is of type 'unknown'
What this error means
The "Object is of type 'unknown'" error is TypeScript's way of enforcing type safety when working with values that could be anything. Unlike the `any` type which allows any operation, `unknown` is a type-safe top type that requires explicit type checking before use. This error typically appears in scenarios like: 1. Working with errors in `catch` blocks (where TypeScript 4.4+ makes caught errors `unknown` by default) 2. Parsing JSON data with `JSON.parse()` 3. Working with values from external APIs or user input 4. Using generic functions that return `unknown` The `unknown` type was introduced in TypeScript 3.0 as a type-safe alternative to `any`. It represents "any possible value" but forces you to verify what you're working with before using it, preventing runtime errors that can occur with `any`.
Typical symptoms
- TypeScript compiler shows "Object is of type 'unknown'" when trying to access properties like `.message` on a caught error
- Code completion and IntelliSense don't show available properties on the value
- The error appears when calling methods or accessing properties on variables typed as `unknown`
- Common in `try/catch` blocks after TypeScript 4.4 where `catch` clause variables are `unknown` by default
Common causes
- Trying to access properties or methods on a value declared as `unknown` without type narrowing
- Working with errors in `catch` blocks without proper type checking (TypeScript 4.4+)
- Using `JSON.parse()` which returns `any` but should be treated as `unknown` for type safety
- Generic functions or APIs that return `unknown` when type parameters aren't specified
- Missing type guards when working with values from external sources like API responses
How to fix "Object is of type 'unknown'"
For errors and other class instances, use instanceof to narrow the type:
try {
// Some code that might throw
} catch (error) {
// TypeScript error: Object is of type 'unknown'
// console.log(error.message); // Error!
if (error instanceof Error) {
// Now TypeScript knows error is an Error
console.log(error.message); // Works!
}
}This is the safest approach for Error objects and other class instances.
For primitive values (string, number, boolean, etc.), use typeof checks:
function processValue(value: unknown) {
// TypeScript error: Object is of type 'unknown'
// value.toUpperCase(); // Error!
if (typeof value === 'string') {
// Now TypeScript knows value is a string
console.log(value.toUpperCase()); // Works!
}
}Common typeof checks: 'string', 'number', 'boolean', 'object', 'function', 'undefined'.
For objects with specific shapes, create reusable type guard functions:
interface ApiResponse {
data: unknown;
status: number;
}
function isApiResponse(obj: unknown): obj is ApiResponse {
return (
typeof obj === 'object' &&
obj !== null &&
'data' in obj &&
'status' in obj &&
typeof (obj as any).status === 'number'
);
}
async function fetchData() {
const response = await fetch('/api/data');
const data: unknown = await response.json();
if (isApiResponse(data)) {
// TypeScript now knows data is ApiResponse
console.log(`Status: ${data.status}`);
}
}Type predicates (obj is ApiResponse) tell TypeScript what type the value is after the check.
If you're absolutely sure about the type, use type assertions (cast with as):
try {
// Some code
} catch (error) {
// Assert error is an Error
const err = error as Error;
console.log(err.message);
// Or inline assertion
console.log((error as Error).message);
}Warning: Type assertions bypass TypeScript's type checking. Only use when you're certain of the type, as wrong assertions cause runtime errors.
If working with legacy code, you can configure TypeScript to use any instead of unknown for catch variables:
// tsconfig.json
{
"compilerOptions": {
"useUnknownInCatchVariables": false
}
}This reverts to pre-TypeScript 4.4 behavior where catch variables are any. Not recommended for new code as it reduces type safety.
Use unknown in function parameters when accepting any value but wanting type safety:
// Safe: Forces callers to handle unknown properly
function safeParse(json: string): unknown {
return JSON.parse(json);
}
// Usage:
const data = safeParse('{"name": "John"}');
if (typeof data === 'object' && data !== null && 'name' in data) {
console.log((data as any).name);
}
// Compare with unsafe version:
function unsafeParse(json: string): any {
return JSON.parse(json);
}
// No type checking required, but runtime errors possible
const unsafeData = unsafeParse('not json');
console.log(unsafeData.name); // Runtime error!Advanced notes
The unknown type is part of TypeScript's type system hierarchy as a top type (along with any). Unlike any, which is both a top and bottom type, unknown is only a top type - it can be assigned to anything, but nothing can be assigned to it without type checking.
Key differences between `unknown` and `any`:
1. any disables all type checking; unknown requires type checking
2. any values can be assigned to any type; unknown values cannot without assertion
3. any allows property/method access; unknown does not
4. any is contagious (makes everything else any); unknown is not
When to use `unknown` vs `any`:
- Use unknown when you need maximum type safety and are willing to do type checking
- Use any only when dealing with truly dynamic code or migrating JavaScript
- Prefer unknown over any for new code
Performance considerations: Type checking with unknown happens at compile time, so there's no runtime overhead. The type guards and assertions are erased during compilation to JavaScript.
Frequently asked questions
- What does "Object is of type 'unknown'" mean?
- The "Object is of type 'unknown'" error is TypeScript's way of enforcing type safety when working with values that could be anything. Unlike the any type which allows any operation, unknown is a type-safe top type that requires explicit type checking before use. This error typically appears in scenarios like: 1.
- How do I fix "Object is of type 'unknown'"?
- This TypeScript error occurs when trying to access properties or methods on a value typed as unknown without first narrowing its type. It's most common in try/catch blocks where caught errors are unknown by default. The fix involves using type guards like instanceof, typeof, or type assertions to safely work with unknown values.
- What causes "Object is of type 'unknown'"?
- Trying to access properties or methods on a value declared as unknown without type narrowing Working with errors in catch blocks without proper type checking (TypeScript 4.4+) Using JSON.parse() which returns any but should be treated as unknown for type safety
- Is the "Object is of type 'unknown'" error serious?
- It is a medium-severity error โ more of a blocker than a risk. The steps above resolve it.
Official resources & further reading
- ๐TypeScript Official Documentation
- ๐
- ๐
- ๐
- ๐Typescriptlang.org - functions.html#unknown(Official Docs)
- ๐