TYPESCRIPT
TypeScript unknown Type: Syntax, Usage, and Examples
The unknown type represents a value that could be anything, but TypeScript won’t let you use it until you prove what it is. It’s the safer alternative to any when you don’t know the type ahead of time.
How to Use the unknown type
You can assign any value to unknown, but you can’t access properties or call methods on it without narrowing.
Learn TypeScript on Mimo
Basic syntax
letinput:unknown;
input ="hello";
input =42;
input = {online:true };
input =null;
That freedom looks like any, but unknown comes with one big rule: you must check the value before using it.
Using unknown forces type checks
This will not compile:
letvalue:unknown ="mimo";
console.log(value.toUpperCase());
TypeScript blocks it because value might not be a string.
To fix it, narrow the type:
letvalue:unknown ="mimo";
if (typeof value ==="string") {
console.log(value.toUpperCase());
}
Assigning unknown to a specific type
You can assign a known type to unknown, but you can’t assign unknown to a known type without checking first.
This works:
lettitle:string ="Dashboard";
letdata:unknown = title;
This does not:
letdata:unknown ="hello";
letname:string = data;// Type error
To safely assign it, narrow it:
letdata:unknown ="hello";
if (typeof data ==="string") {
letname:string = data;
}
Using unknown in functions
A common pattern is to accept an unknown input and validate inside the function.
functionprintLength(value:unknown) {
if (typeof value ==="string") {
console.log(value.length);
}else {
console.log("Not a string, no length to print.");
}
}
printLength("Vienna");
printLength(99);
unknown arrays
unknown[] means “an array of values, but I don’t know what each value is yet.”
constitems:unknown[] = [1,"two",false];
for (const itemof items) {
if (typeof item ==="string") {
console.log(item.toUpperCase());
}
}
When to Use the unknown type
Use unknown when you truly don’t know what will arrive at runtime, but you still want TypeScript to keep you honest.
1) Working with API responses or JSON
APIs can change, or they can return weird data when something goes wrong. unknown makes you validate before using it.
asyncfunctiongetUserData():Promise<unknown> {
const response =awaitfetch("/api/user");
return response.json();
}
Later, you narrow it before accessing fields.
2) Accepting user input from forms
Form inputs often come in as strings, but you might treat them as numbers or booleans after parsing.
functionparseAge(input:unknown) {
if (typeof input ==="string") {
const numberAge =Number(input);
if (!Number.isNaN(numberAge)) {
return numberAge;
}
}
returnnull;
}
unknown helps prevent accidentally treating a random value as a valid number.
3) Handling errors safely in catch blocks
In modern TypeScript, catch (error) is treated as unknown in many setups.
try {
JSON.parse("broken json");
}catch (error:unknown) {
if (errorinstanceofError) {
console.log(error.message);
}else {
console.log("Something unexpected happened.");
}
}
This avoids assuming error always has .message.
4) Writing reusable utility functions
Generic utilities often accept inputs from lots of places. unknown makes them safer by forcing checks.
functionsafeToString(value:unknown):string {
if (typeof value ==="string")return value;
if (typeof value ==="number")return value.toString();
return"Unsupported value";
}
Examples of the unknown type
Here are some realistic examples that show how unknown protects you from easy mistakes.
Example 1: Parsing JSON safely
const raw ='{"name":"Lea","role":"admin"}';
constdata:unknown =JSON.parse(raw);
if (typeof data ==="object" && data !==null &&"name"in data) {
const user = dataas {name:string };
console.log(user.name);
}
This is more work than any, but it stops you from doing data.name on a number, null, or something unexpected.
Example 2: Narrowing with typeof checks
functionformatValue(value:unknown) {
if (typeof value ==="string") {
return value.trim();
}
if (typeof value ==="number") {
return value.toFixed(2);
}
return"Unsupported type";
}
console.log(formatValue(" 5 "));
console.log(formatValue(3.5));
console.log(formatValue(true));
TypeScript understands each branch, so you get safe method access like .trim() and .toFixed().
Example 3: Validating a dynamic object
Imagine you receive a settings object from localStorage.
conststored:unknown =JSON.parse('{"theme":"dark","fontSize":16}');
typeSettings = {
theme:string;
fontSize:number;
};
functionisSettings(value:unknown): value isSettings {
if (typeof value !=="object" || value ===null)returnfalse;
const obj = valueasRecord<string,unknown>;
return (
typeof obj.theme ==="string" &&
typeof obj.fontSize ==="number"
);
}
if (isSettings(stored)) {
console.log(stored.theme);
console.log(stored.fontSize);
}else {
console.log("Invalid settings format, using defaults.");
}
That isSettings function is a type guard. It tells TypeScript, “After this check, you can trust the type.”
Example 4: unknown in event-driven code
Sometimes you get data from a message event (like browser messaging or WebSocket).
functionhandleMessage(payload:unknown) {
if (typeof payload ==="string") {
console.log("Message:", payload);
return;
}
if (typeof payload ==="object" && payload !==null) {
console.log("Object message received.");
return;
}
console.log("Unsupported payload type.");
}
You can support multiple input shapes without letting anything slide through silently.
Learn More About the unknown type
unknown is powerful, but it becomes much easier once you know the patterns TypeScript expects.
unknown vs any
The difference is simple:
anylets you do anything, even unsafe thingsunknownmakes you check first
Example with any:
letdata:any ="hello";
console.log(data.toUpperCase());// allowed
Example with unknown:
letdata:unknown ="hello";
console.log(data.toUpperCase());// blocked
With unknown, TypeScript won’t let you accidentally call string methods on a number.
Common narrowing techniques
Here are the most common ways to narrow a value:
typeof checks
functioncheck(value:unknown) {
if (typeof value ==="boolean") {
return value ?"yes" :"no";
}
return"not a boolean";
}
instanceof checks
Useful for error objects, Dates, and class instances.
functionhandleError(error:unknown) {
if (errorinstanceofError) {
console.log(error.message);
}
}
in operator for objects
Good for checking properties.
functionhasId(value:unknown) {
if (typeof value ==="object" && value !==null &&"id"in value) {
const obj = valueas {id:unknown };
return obj.id;
}
returnnull;
}
Type guards make code cleaner
Type guards are reusable checks you can call everywhere.
typeProduct = {
id:number;
name:string;
};
functionisProduct(value:unknown): value isProduct {
if (typeof value !=="object" || value ===null)returnfalse;
const obj = valueasRecord<string,unknown>;
returntypeof obj.id ==="number" &&typeof obj.name ==="string";
}
Then you get safe access:
constinput:unknown = {id:1,name:"Keyboard" };
if (isProduct(input)) {
console.log(input.name.toUpperCase());
}
unknown works well with generics
Sometimes you want a function that can accept unknown input, then return a known type after validation.
function parseJSON<T>(raw:string): T {
returnJSON.parse(raw)as T;
}
typeUser = {name:string };
const user = parseJSON<User>('{"name":"Noor"}');
console.log(user.name);
This uses a type assertion, so you still need to be careful, but it’s a common pattern for controlled data.
A practical rule of thumb
Use unknown when:
- you receive data from outside your code
- you parse JSON
- you handle errors
- you accept flexible input in a shared utility
Use a specific type or a union type when:
- you know the shape of the data
- the value can only be one of a few types
If unknown feels annoying at first, that’s normal. The extra checks are the point.
Summary
The unknown type is a safe way to represent values you don’t know yet. You can assign anything to it, but you must narrow the type before using it.
It’s a great fit for API responses, user input, error handling, and reusable utilities, especially when you want TypeScript to catch mistakes before runtime.
Join 35M+ people learning for free on Mimo
4.8 out of 5 across 1M+ reviews
Check us out on Apple AppStore, Google Play Store, and Trustpilot