How to Use Unknown Type in TypeScript

What you’ll build or solve

You’ll declare variables, parameters, and return values as unknown when the type is not known yet.

When this approach works best

Using unknown works best when you:

  • Parse JSON from an API and do not fully trust the structure
  • Accept user input from forms or external systems
  • Replace any with something safer during refactoring

It also helps when building reusable utilities that receive data from many sources.

This is a bad idea if you already know the exact shape of the data. In that case, define an interface or type instead of using unknown.

Prerequisites

  • TypeScript installed
  • A .ts file
  • Basic understanding of types and interfaces

Step-by-step instructions

Step 1: Use the unknown type annotation

Add : unknown when the type is not known yet.

Basic variable

letvalue:unknown;

value="hello";
value=42;
value= { name:"Alex" };

Function parameter

functionlogData(data:unknown) {
console.log(data);
}

Return type

functionparseJson(json:string):unknown {
returnJSON.parse(json);
}

In all cases, unknown accepts any value. The key difference from any is that you cannot directly access properties or call methods without narrowing first.

For example, this does not compile:

letinput:unknown="Sam";

input.toUpperCase();// Error

TypeScript blocks this because the type is not confirmed.

What to look for

  • You can assign any value to unknown
  • You cannot access properties or call methods directly
  • The compiler forces you to narrow before usage
  • unknown is safer than any
  • Replace unknown with a specific type once the structure is stable
  • Use type guards such as typeof, instanceof, in, or custom predicates to narrow values
  • See the separate guide on using type guards for full narrowing patterns

Examples you can copy

Example 1: Safer JSON parsing

functionparseConfig(json:string):unknown {
returnJSON.parse(json);
}

constconfig=parseConfig('{"theme":"dark"}');

Here, config is unknown. You cannot access config.theme until you validate its shape. This prevents accidental runtime errors if the JSON structure changes.

Example 2: Accepting flexible input

functionhandleInput(input:unknown) {
returninput;
}

This allows the function to accept any value without losing type safety. The caller must narrow the value before using it in a type-specific way.

Example 3: Replacing any during refactoring

Before

functionprocess(data:any) {
returndata.id;
}

After

functionprocess(data:unknown) {
returndata;
}

Switching to unknown forces you to validate data before accessing id. This exposes unsafe assumptions and improves reliability.

Common mistakes and how to fix them

Mistake 1: Treating unknown like any

You might write:

functionprint(value:unknown) {
console.log(value.toUpperCase());
}

Why it breaks: TypeScript does not allow method calls on unknown.

Correct approach:

functionprint(value:unknown) {
if (typeofvalue==="string") {
console.log(value.toUpperCase());
  }
}

Narrow the value first using a type guard.

Mistake 2: Switching to unknown but never narrowing

You might write:

functiongetId(data:unknown) {
return (dataas { id:number }).id;
}

Why it breaks: This bypasses safety and behaves like any.

Correct approach:

functiongetId(data:unknown) {
if (
typeofdata==="object"&&
data!==null&&
"id"indata
  ) {
return (dataas { id:number }).id;
  }

returnnull;
}

Validate before accessing properties. Use proper type guards instead of forcing a cast.

Troubleshooting

  • If you see “Object is of type unknown”, add a type guard before accessing properties.
  • If autocomplete does not show methods, confirm the variable is narrowed inside the current block.
  • If switching from any to unknown causes many errors, that usually means unsafe assumptions existed before. Fix them by validating data.
  • If strict mode produces new errors after using unknown, review each usage and narrow appropriately.

Quick recap

  • unknown accepts any value but blocks unsafe usage
  • You cannot access properties or call methods without narrowing
  • Use it for API responses, JSON parsing, and user input
  • Prefer unknown over any for safer flexibility
  • Replace unknown with specific types once the structure is clear