Understanding unknown vs any
Why unknown is the type-safe alternative to any.
Understanding unknown vs any is a free TypeScript Academy lesson on CoddyKit — lesson 1 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the TypeScript Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
Two Top Types
TypeScript has two types that can hold any value: any and unknown. They look similar but behave very differently. Choosing the right one is a core skill for type-safe code.
let a: any = 5;
let u: unknown = 5;
console.log(a, u);any Disables Type Checking
any is an escape hatch that turns off the type checker for that value. You can access any property or call it like a function — the compiler stays silent, even when it would crash at runtime.
const a: any = 'hello';
console.log(a.toUpperCase()); // OK
// a.doesNotExist(); // no compile error, but crashes at runtimeunknown Forces You to Check
unknown accepts any value too, but you cannot use it until you prove what it is. The compiler blocks property access and calls until you narrow the type.
const u: unknown = 'hello';
// console.log(u.toUpperCase()); // Error: u is unknown
console.log(typeof u);Narrowing unknown With typeof
A typeof guard narrows unknown to a concrete type inside the block. Once narrowed, all the methods of that type become available safely.
function shout(value: unknown): string {
if (typeof value === 'string') {
return value.toUpperCase(); // safe here
}
return 'not a string';
}
console.log(shout('hi'), shout(42));Why unknown Is Safer
unknown represents honest uncertainty: 'I don't know what this is yet.' It pushes you to validate before use, catching bugs at compile time. any just hides the uncertainty and the bugs.
function len(value: unknown): number {
if (typeof value === 'string') return value.length;
if (Array.isArray(value)) return value.length;
return 0;
}
console.log(len('abc'), len([1, 2]), len(99));Assigning To and From unknown
Any value is assignable to unknown. But unknown is assignable only to unknown or any — not to specific types without narrowing. This asymmetry is what keeps it safe.
let u: unknown = 10;
u = 'now a string';
u = true;
const anyVal: any = u; // allowed
console.log(anyVal);
// const s: string = u; // Errorany Spreads Through Your Code
A dangerous trait of any is that it spreads. Once a value is any, anything derived from it becomes any too, silently eroding type safety across your program.
const a: any = { count: 5 };
const total = a.count + 10; // total is any
const flag = total.whatever; // still any, no error
console.log(total);unknown Contains the Risk
With unknown, the uncertainty stays put. You must explicitly narrow at each boundary, so unsafe operations cannot leak elsewhere. The risk is contained where it belongs.
const u: unknown = { count: 5 };
if (typeof u === 'object' && u !== null && 'count' in u) {
console.log('Has count property');
}Typing API and JSON Boundaries
External data — JSON, network responses, user input — has no guarantees. Typing it as unknown instead of any forces validation before you trust it, which is the safe default.
function parse(text: string): unknown {
return JSON.parse(text);
}
const data = parse('{"id":1}');
if (typeof data === 'object' && data !== null) {
console.log('Got an object');
}When any Is Acceptable
any is occasionally pragmatic — quick prototypes, gradual migration from JavaScript, or interop with untyped libraries. But treat it as a temporary marker, not a habit. Prefer unknown whenever you can.
// Migration placeholder, to be typed later
let legacy: any = getLegacyValue();
function getLegacyValue() { return { x: 1 }; }
console.log(legacy.x);A Practical Comparison
Side by side: the any version compiles but can crash; the unknown version refuses to compile the unsafe access. The compiler is doing its job — protecting you.
const a: any = 42;
console.log(a.toFixed(2)); // OK by luck
const u: unknown = 42;
if (typeof u === 'number') {
console.log(u.toFixed(2)); // checked, safe
}Quick Check
Test your understanding of unknown vs any.
Recap: unknown vs any
Key points:
anydisables type checking and spreads through derived values.unknownaccepts any value but blocks use until you narrow it.- Use
unknownfor external data (JSON, APIs, user input) to force validation. - Reserve
anyfor migration or untyped interop, as a temporary marker.
Next, we explore the empty type: never.
function safeLen(v: unknown): number {
return typeof v === 'string' ? v.length : 0;
}
console.log(safeLen('hello'), safeLen(123));Frequently asked questions
Is the “Understanding unknown vs any” lesson free?
Yes — the full text of “Understanding unknown vs any” is free to read here on the web, and the TypeScript Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the TypeScript Academy course, upgrade to CoddyKit PRO.
What will I learn in “Understanding unknown vs any”?
Why unknown is the type-safe alternative to any. You practise TypeScript Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start TypeScript Academy?
No prior experience is required. TypeScript Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 1 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Understanding unknown vs any” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this TypeScript Academy lesson?
Yes. Every TypeScript Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.
All lessons in this course
- Understanding unknown vs any
- The never Type and Impossible States
- The void Type in Functions
- Type-Safe Handling of unknown