any vs unknown
any turns off type checking and allows anything, while unknown also accepts any value but requires a type check before you can use it.
Side-by-side comparison
#Accepts any value
Use without a type check
Calling any method
Assigning to another type without a check
Where the error surfaces
Typical use
Example
#function describeAny(value: any): string {
return value.toUpperCase()
}
function describeUnknown(value: unknown): string {
if (typeof value === 'string') return value.toUpperCase()
return 'unknown type'
}
console.log(describeAny('html'))
console.log(describeUnknown('css'))
console.log(describeUnknown(42))HTML CSS unknown type
Definition and usage
#Both types accept a value of any kind: you can assign a string, a number, an object, or the result of JSON.parse() to an any or unknown variable. In both cases the compiler has no idea up front what the value actually is.
The difference is in what you’re allowed to do next. With an any value you can call any method right away and pass it anywhere, with no check at all, because the compiler stops watching types. With an unknown value you can’t do anything until you narrow the type with typeof, instanceof, Array.isArray(), or your own type guard. Only after such a check does the compiler expose the methods that belong to the recognized type.
any is a trapdoor that switches TypeScript off wherever you use it, and it’s easy to let a bug slip through it into the running program. unknown gives you the same flexibility when accepting data, but forces you to check it, so for data from outside (an API, JSON.parse(), localStorage) choose unknown. Leave any as a temporary fix while migrating from JavaScript.
Syntax
#let value: any
let other: unknownMore examples
#const broken: any = { user: null }
try {
console.log(broken.user.name)
} catch (error) {
console.log('Runtime error, the compiler flagged nothing')
}Runtime error, the compiler flagged nothing
const input: unknown = JSON.parse('{"level":7}')
console.log(input.level)
// Error: 'input' is of type 'unknown'.Good practices
#- Turn on the
noImplicitAnyoption, so the compiler doesn’t silently acceptanywherever you didn’t give a type. - The error in
catch (error)has the typeunknown. Checkerror instanceof Errorbefore you readerror.message. - If you migrate code from
anytounknown, the compiler itself will point out every place that needs a type check.
Related entries
#Spotted a mistake or missing an example? Write to us.