Both can hold any value, but they differ in safety. any switches off type checking; unknown keeps it on and forces you to narrow before use.
ts
: = ;
a..;
();
: = ;
u.();
();
Both can hold any value, but they differ in safety. any switches off type checking; unknown keeps it on and forces you to narrow before use.
: = ;
a..;
();
: = ;
u.();
();
function handle(input: unknown) {
if (typeof input === "string") {
input.toUpperCase(); // ✅ inside the guard, TS knows it's a string
}
}
unknown is the type-safe counterpart of any: you can assign anything to it, but you can't do anything with it until you prove what it is via a type guard.
unknown — for values of genuinely unknown type at the boundary: JSON.parse results, API responses, catch (e: unknown). It forces validation.any — escape hatch when migrating JS or when you truly can't type something. Use sparingly; it spreads silently and disables safety.Reaching for any defeats the purpose of TypeScript.
Prefer unknown at untyped boundaries — it keeps the compiler's guarantees while still accepting arbitrary input, pushing you to validate data before trusting it.