Lesson 5 of 80
Both can hold any value — but any switches off type checking entirely, while unknown forces you to prove what something is before you can use it.
11 min read
Every option explains itself — why the right one is right, and why each wrong one is wrong. Miss one and it comes back later on a spaced-repetition schedule.
Question 1 of 3
A function returns unknown. Can you immediately call a method on the returned value, the way you could with any?
Hints without spoilers, and a plain explanation of why a wrong answer was wrong — answered only from this lesson. Free account, no card.
Sign up freeWhat interviewers actually ask about this, and what a strong answer has to cover.
A strong answer covers
Likely follow-ups
any and unknown can both hold a value of any type. That's where the similarity ends.
any turns off type checking for that value completely. You can call any method, access any property, pass it anywhere — the compiler stays silent, even if it's wrong.unknown also accepts any value, but you can't do anything with it until you narrow it down to something more specific first.function parseAny(json: string): any {
return JSON.parse(json);
}
const a = parseAny('{"name": "Ada"}');
a.name.toUpperCase(); // "type-checks" — even if a turns out to be a number
function parseUnknown(json: string): unknown {
return JSON.parse(json);
}
const b = parseUnknown('{"name": "Ada"}');
b.name; // ❌ compile error — b is unknown, nothing is accessible yet
if (typeof b === "object" && b !== null && "name" in b) {
console.log(b.name); // ✅ now it's narrowed enough to use
}
parseAny's result lets you write a.name.toUpperCase() with zero pushback, even though nothing has actually confirmed a has a .name at all. parseUnknown refuses to let you touch b until you've proven something about its shape — exactly the discipline you want for data you don't control, like a network response.
let x: any = fetchData(); x.toUpperCase().whatever() — any turns off type checking completely. No safety net.
any is contagious. Anything derived from an any-typed value silently becomes any too — one loose any deep in a codebase can quietly erase type safety across everything that touches it.unknown is assignable from anything, but not assignable to other types without narrowing first. any breaks the type system in both directions — assignable both to and from everything, which is exactly what makes it dangerous rather than merely permissive.any value to a new variable makes that variable any too (unless explicitly annotated otherwise); assigning an unknown value to a new variable keeps it unknown — the safety doesn't leak away just by moving the value around.noImplicitAny (a common tsconfig.json setting) turns every implicit any — a parameter or variable TypeScript couldn't infer a type for — into a compile error, instead of silently letting it become any. It's usually one of the first settings turned on when tightening a codebase."When would you use unknown instead of any?" tests whether you understand that any isn't a convenient shortcut with no downside — it's a deliberate opt-out of the entire type system, and unknown is what "I genuinely don't know the type yet" should look like when you still want the compiler's help.