Any vs Unknown: Mastering TypeScript Type Safety
Stop using 'any' and start writing safer code. Learn why 'unknown' is the superior choice for handling dynamic data in TypeScript and how to use it properly.

Previously in this course, we explored Mastering the Typeof Guard in TypeScript for Runtime Safety to handle data at runtime. In this lesson, we shift our focus from narrowing known types to managing data when we have no idea what it is, specifically by replacing the permissive any type with the strict unknown type.
The Problem with 'any'
When you use any, you are effectively telling the TypeScript compiler: "Stop checking this variable, I know what I'm doing." While this might seem convenient, it is the single most common cause of runtime crashes in TypeScript applications.
any disables all type-checking. You can call methods that don't exist, pass variables to functions that expect different shapes, and access properties that aren't there—all without a single warning from your IDE.
TYPESCRIPTlet userData: any = "admin"; userData.toUpperCase(); // Fine userData.nonExistentMethod(); // No compiler error, but will crash at runtime!
Why 'unknown' is the Better Alternative
Introduced as a type-safe counterpart to any, unknown forces you to perform a check before you can interact with a value. It is the "top type"—anything can be assigned to unknown, but you cannot perform operations on an unknown value until you narrow it down.
Think of unknown as a locked box. You know there is something inside, but you can't touch it until you verify what it is.
| Feature | any | unknown |
|---|---|---|
| Type Checking | Disabled | Enabled |
| Property Access | Allowed | Disallowed |
| Method Invocation | Allowed | Disallowed |
| Requires Guarding | No | Yes |
Worked Example: Safely Parsing API Data
In our ongoing Task API project, we often receive raw JSON from fetch. If we don't know the structure, we shouldn't cast it to our Task interface immediately. Instead, we treat it as unknown.
TYPESCRIPTinterface Task { id: number; title: string; } // Imagine this comes from an external, untyped source const rawResponse: unknown = JSON.parse(CE9178">'{"id": 1, "title": "Finish Lesson"}'); // Attempting this will throw a compile-time error: // console.log(rawResponse.title); // Error: Object is of type CE9178">'unknown' // We must narrow the type first if (typeof rawResponse === CE9178">'object' && rawResponse !== null && CE9178">'title' in rawResponse) { // TypeScript now knows CE9178">'rawResponse' has a title property const task = rawResponse as Task; console.log(task.title); }
Hands-on Exercise
- Create a variable called
apiPayloadand set its type tounknown. - Assign it an object representing a task:
{ id: 101, status: 'pending' }. - Try to access
apiPayload.iddirectly. Observe the error. - Use a
typeofcheck or theinoperator (as discussed in The In Operator for Object Narrowing in TypeScript) to verify the object structure before logging theidto the console.
Common Pitfalls
- The "Lazy" Cast: Developers often use
as Taskimmediately after receiving data from an API. This is just as dangerous asany. Always validate the structure (e.g., using a library like Zod or simpleinchecks) before asserting a type. - Assuming Non-Null: Remember that
typeof nullis'object'. Always checkvalue !== nullwhen validating if anunknownvalue is an object. - Forgetting Narrowing: If you find yourself writing
asrepeatedly, you are likely missing an opportunity to use Type Narrowing with Conditionals in TypeScript to handle the logic flow more naturally.
FAQ
Can I assign unknown to other types?
Only to any and unknown. You cannot assign unknown to a string or number without explicitly checking the value first.
Is there ever a reason to use any?
Very rarely. It is sometimes used as an escape hatch when dealing with poorly typed legacy third-party libraries, but even then, creating a custom .d.ts declaration file is a better long-term strategy.
Does unknown affect performance?
No. TypeScript types are erased at compile time. unknown is a tool for the developer and the compiler, not the JavaScript engine.
Recap
anyis a "blindfold" that disables type safety.unknownis a "guard" that requires explicit validation.- Always prefer
unknownoveranywhen the shape of the data is uncertain. - Narrow your
unknowntypes usingtypeof,in, or custom type guards before accessing properties.
Up next: We will dive into Generics to make our code more reusable without sacrificing the safety we've worked so hard to build.
Work with me

Next.js Full-Stack Web App Development
A fast, SEO-ready full-stack web app built with Next.js 16 — from idea to deployed product, by an engineer who ships to production.

React & Next.js Dashboard / Admin UI Development
A clean, data-rich dashboard UI in React or Next.js — charts, tables, and real-time data that your users will actually enjoy using.