TypeScript Any vs Unknown
Both unknown
and any
types can contain any value, and any value can be assigned to either one. However unknown
is considered the type-safe counter-part to any
because you must first narrow down the type before performing any operations.
any
Here’s an example of any
where our anyValue
variable can contain any value as well as any operation can be performed on it even if it will throw a runtime error.
let anyValue: any
// assign any value you want!
anyValue = () => console.log('bisquits and gravy')
anyValue = ['pizza', 'hamburger', 'salad']
// perform any operation you want!
const alphabetical = anyValue.sort()
const upperCase = anyValue.toUpperCase()
TypeScript will not complain but this will throw a runtime error because anyValue
is not of type string. TypeError: anyValue.toUpperCase is not a function
.
unknown
Here’s the same example using unknown
, we are able to catch the error in the code before the code runs and fails.
let unknownValue: unknown
// assign any value you want!
unknownValue = () => console.log('bisquits and gravy')
unknownValue = ['pizza', 'hamburger', 'salad']
// We get an error: 'unknownValue' is of type 'unknown'.
❌ const alphabetical = unknownValue.sort()
❌ const upperCase = unknownValue.toUpperCase()
// We must narrow the type before performing an operation
✅
let alphabetical: string[]
if (Array.isArray(unknownValue)) {
alphabetical = unknownValue.sort()
}
✅
let upperCase: string
if(typeof unknownValue === 'string') {
upperCase = unknownValue.toUpperCase()
}
The above if(typeof unknownValue === 'string')
statement will be false, therefore avoiding a runtime error.
Which one to use
any
can be useful during development when converting JavaScript projects to TypeScript, however with any
we’re essentially turning TypeScript off. unknown
should always be preferred instead of any
because we still get the benefits of TypeScript's type system without knowing the type ahead of time.