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
let input: 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:
let value: unknown = "mimo";
console.log(value.toUpperCase());
TypeScript blocks it because value might not be a string.
To fix it, narrow the type:
let value: 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:
let title: string = "Dashboard";
let data: unknown = title;
This does not:
let data: unknown = "hello";
let name: string = data; // Type error
To safely assign it, narrow it:
let data: unknown = "hello";
if (typeof data === "string") {
let name: string = data;
}
Using unknown in functions
A common pattern is to accept an unknown input and validate inside the function.
function printLength(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.”
const items: unknown[] = [1, "two", false];
for (const item of 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.
async function getUserData(): Promise<unknown> {
const response = await fetch("/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.
function parseAge(input: unknown) {
if (typeof input === "string") {
const numberAge = Number(input);
if (!Number.isNaN(numberAge)) {
return numberAge;
}
}
return null;
}
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 (error instanceof Error) {
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.
function safeToString(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"}';
const data: unknown = JSON.parse(raw);
if (typeof data === "object" && data !== null && "name" in data) {
const user = data as { 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
function formatValue(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.
const stored: unknown = JSON.parse('{"theme":"dark","fontSize":16}');
type Settings = {
theme: string;
fontSize: number;
};
function isSettings(value: unknown): value is Settings {
if (typeof value !== "object" || value === null) return false;
const obj = value as Record<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).
function handleMessage(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:
let data: any = "hello";
console.log(data.toUpperCase()); // allowed
Example with unknown:
let data: 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
function check(value: unknown) {
if (typeof value === "boolean") {
return value ? "yes" : "no";
}
return "not a boolean";
}
instanceof checks
Useful for error objects, Dates, and class instances.
function handleError(error: unknown) {
if (error instanceof Error) {
console.log(error.message);
}
}
in operator for objects
Good for checking properties.
function hasId(value: unknown) {
if (typeof value === "object" && value !== null && "id" in value) {
const obj = value as { id: unknown };
return obj.id;
}
return null;
}
Type guards make code cleaner
Type guards are reusable checks you can call everywhere.
type Product = {
id: number;
name: string;
};
function isProduct(value: unknown): value is Product {
if (typeof value !== "object" || value === null) return false;
const obj = value as Record<string, unknown>;
return typeof obj.id === "number" && typeof obj.name === "string";
}
Then you get safe access:
const input: 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 {
return JSON.parse(raw) as T;
}
type User = { 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