Introduction
What are Any
and Unknown
in TypeScript?
Any
Type as a Top Type
The A top type is a universal type that acts as a parent type to other types.
In the context of TypeScript, the type Any
can represent any other type. Any
can represent
String
, Number
, Object
, and other types available in TypeScript.
What if a function assigned to an object does not exist, but we want to call it?
let obj: any = { x: 0 };
obj.foo(); // no compiler error
Any
?
What if we want to call a variable of type let obj: any = { x: 0 };
obj(); // no compiler error
obj
object?
What if we initialize a new property on the let obj: any = { x: 0 };
obj.bar = '100'; // no compiler error
obj
variable?
What if we assign a different value to the let obj: any = { x: 0 };
obj = "test"; // no compiler error
obj
to another variable with a specified type?
What if we assign the value of let obj: any = { x: 0 };
const n: number = obj; // no compiler error
noImplicitAny
Sometimes, the TypeScript compiler is unable to infer the type from the context of the written code. In such cases, the default type that is assigned is any. To prevent this and increase type safety, we can add a flag called --noImplicitAny to the command that runs TypeScript compilation. This flag can also be added to the tsconfig.json file with a value of true. Adding this flag will cause a compiler error, informing us that implicit any type annotations are not allowed on variables, function parameters, etc. You get the idea.
noImplicitAny: true,
Example code with the noImplicitAny
flag enabled:
// the compiler will notify us of an error
function fn(s) { // Parameter 's' implicitly has an 'any' type.
console.log(s.subtr(3));
}
fn(42);
The Unknown Type as a Top Type (Surprisingly, a Second Top Type)
The Unknown
type is a safer way to manage variable values, function parameters, etc.
It requires that we first check the type of the variable or parameter.
Here are some ways to handle the Unknown
type:
Type Assertion
function func(value: unknown) {
value.toFixed(2); // compiler notifies of an error
// Type assertion
// compiler does not notify of an error
(value as number).toFixed(2);
}
Value Comparison
function func(value: unknown) {
value * 5; // compiler notifies of an error
if (value === 123) { // comparison
value * 5; // compiler does not notify of an error
}
}
Type guards
function func(value: unknown) {
value.length; // compiler notifies of an error
if (typeof value === 'string') { // type guard
value.length; // compiler does not notify of an error
}
}
Assertion functions
function func(value: unknown) {
value.test('abc'); // compiler notifies of an error
assertIsRegExp(value);
value.test('abc'); // compiler does not notify of an error
}
function assertIsRegExp(arg: unknown): asserts arg is RegExp {
if (! (arg instanceof RegExp)) {
throw new TypeError('Not a RegExp: ' + arg);
}
}