TypeScript

unknown in TypeScript – The Safer Alternative to any

TypeScript was designed to give strong type safety while keeping the flexibility of JavaScript. The any type often becomes a quick escape hatch, but it removes all compile-time checks.

To solve this problem, TypeScript introduced unknown, a type that behaves similarly to any (it can accept any value), but with safer restrictions.

Let’s explore what unknown is, how it differs from any, and why it should be your default choice when the type is not yet known.


What is unknown in TypeScript?

  • unknown is the type-safe counterpart of any.
  • Like any, it can hold any value.
  • Unlike any, you cannot directly use the value without narrowing its type first.
let value: unknown;

value = 42;       // OK
value = "hello";  // OK
value = { x: 1 }; // OK

// But direct usage is not allowed:
console.log(value.toUpperCase()); 
// ❌ Error: Object is of type 'unknown'

To use an unknown value, you must check or assert its type first:

if (typeof value === "string") {
  console.log(value.toUpperCase()); // ✅ Safe
}

any vs unknown in Type Hierarchy

In TypeScript’s type system, every type is connected by subtype and supertype relations.

  • any is both a supertype and subtype of all types.
    • It can be assigned to anything, and anything can be assigned to it.
    • This is why any is dangerous — it bypasses the type system.
  • unknown is a supertype of all types, but it is not a subtype of anything except itself and any.
    • You can assign any value to unknown.
    • But you cannot assign unknown to other types without explicit checking.

Example:

let val: unknown;

val = 123;          // OK
val = "text";       // OK

let str: string;
// str = val;       // ❌ Error: unknown not assignable to string
str = val as string; // ✅ Explicit cast required

This restriction prevents silent bugs.


Example: Using unknown in API Responses

Imagine you fetch JSON from an API. The shape of the data is not guaranteed:

function parseApiResponse(json: string): unknown {
  return JSON.parse(json);
}

const result = parseApiResponse('{"id": 1, "name": "Alice"}');

// result.id ❌ Error (unknown)
// Must validate first:
if (typeof result === "object" && result !== null && "name" in result) {
  console.log((result as { name: string }).name); // ✅ Safe
}

With any, this would compile but might crash at runtime. With unknown, you’re forced to validate before usage.


unknown vs any – Comparison Table

Featureanyunknown
Accepts all values✅ Yes✅ Yes
Assignable to all types✅ Yes❌ No (only to any and unknown)
Allows arbitrary property access✅ Yes❌ No (requires type check)
Allows arbitrary function calls✅ Yes❌ No (requires type check)
Safe by default❌ No✅ Yes
Subtype relationsSubtype and supertype of all typesOnly supertype of all types (subtype of any and itself)
Best use caseQuick prototyping, legacy JS migration (not recommended long term)When the type is unknown yet must be validated safely

Best Practices with unknown

✅ Use unknown instead of any whenever you don’t know the type up front.
✅ Perform type narrowing with typeof, instanceof, or custom type guards.
✅ Use unknown for API responses, dynamic inputs, or third-party data.
✅ Avoid using any in strict TypeScript projects — enforce with ESLint:

"rules": {
  "@typescript-eslint/no-explicit-any": "error"
}

Conclusion

  • any removes all type safety and should be avoided in production code.
  • unknown gives the same flexibility but forces type safety at usage time.
  • In TypeScript’s type system:
    • any is both supertype and subtype.
    • unknown is only a supertype (cannot silently flow into stricter types).

👉 If you ever feel the urge to use any, use unknown instead — it’s the safe analogue that will protect your project from subtle runtime errors.


Related posts
TypeScript

Literals in TypeScript: String, Number, Boolean, Template, and Compound Literals

Literals are one of the fundamental building blocks of TypeScript programming. They represent fixed…
Read more
TypeScript

Utility Types in TypeScript: Pick, Omit, Partial, Required, Readonly, Record...

✅ — Utility Types are one of the most powerful features of TypeScript, but also one of the most…
Read more
TypeScript

Complete TypeScript Tutorial Online: Master TypeScript in 2025

TypeScript has revolutionized modern web development by bringing static typing to JavaScript, making…
Read more