'unknown' vs. 'any'
Solution 1:
You can read more about unknown
in the PR or the RC announcement, but the gist of it is:
[..] unknown which is the type-safe counterpart of any. Anything is assignable to unknown, but unknown isn't assignable to anything but itself and any without a type assertion or a control flow based narrowing. Likewise, no operations are permitted on an unknown without first asserting or narrowing to a more specific type.
A few examples:
let vAny: any = 10; // We can assign anything to any
let vUnknown: unknown = 10; // We can assign anything to unknown just like any
let s1: string = vAny; // Any is assignable to anything
let s2: string = vUnknown; // Invalid; we can't assign vUnknown to any other type (without an explicit assertion)
vAny.method(); // Ok; anything goes with any
vUnknown.method(); // Not ok; we don't know anything about this variable
The suggested usage is:
There are often times where we want to describe the least-capable type in TypeScript. This is useful for APIs that want to signal “this can be any value, so you must perform some type of checking before you use it”. This forces users to safely introspect returned values.
Solution 2:
The difference between unknown and any is described as:
Much like
any
, any value is assignable tounknown
; however, unlikeany
, you cannot access any properties on values with the typeunknown
, nor can you call/construct them. Furthermore, values of typeunknown
can only be assigned tounknown
orany
.
To answer your question of when should you use unknown
over any
:
This is useful for APIs that want to signal “this can be any value, so you must perform some type of checking before you use it”. This forces users to safely introspect returned values.
Take a look at the TypeScript 3.0 announcement for examples of type checking a variable of type unknown
and a more detailed explanation.
Solution 3:
any
type:
The any
type represents all possible JS values. Every type is assignable to type any
. Therefore the type any
is an universal supertype of the type system. The TS compiler will allow any operation on values typed any
. For example:
let myVar: any;
myVar[0];
myVar();
myVar.length;
new myVar();
In many occasions this is too lenient of the TS compiler. i.e. it will allow operations which we could have known to be resulting into a runtime error.
unknown
type:
The unknown
type represents (just like any
) all possible JS values. Every type is assignable to type unknown
. Therefore the type unknown
is another universal supertype of the type system (alongside any
). However, the TS compiler won't allow any operation on values typed unknown
. Furthermore, the unknown
type is only assignable to the type any
. An example will clarify this:
let myVar: unknown;
let myVar1: unknown = myVar; // No error
let myVar2: any = myVar; // No error
let myVar3: boolean = myVar; // Type 'unknown' is not assignable to type 'boolean'
// The following operations on myVar all give the error:
// Object is of type 'unknown'
myVar[0];
myVar();
myVar.length;
new myVar();