Tackling TypeScript
Please support this book: buy it or donate
(Ad, please don’t block.)

11 The top types any and unknown

In TypeScript, any and unknown are types that contain all values. In this chapter, we examine what they are and what they can be used for.

11.1 TypeScript’s two top types

any and unknown are so-called top types in TypeScript. Quoting Wikipedia:

The top type […] is the universal type, sometimes called the universal supertype as all other types in any given type system are subtypes […]. In most cases it is the type which contains every possible [value] in the type system of interest.

That is, when viewing types as sets of values (for more information on what types are, see [content not included]), any and unknown are sets that contain all values. As an aside, TypeScript also has the bottom type never, which is the empty set.

11.2 The top type any

If a value has type any, we can do everything with it:

function func(value: any) {
  // Only allowed for numbers, but they are a subtype of `any`
  5 * value;

  // Normally the type signature of `value` must contain .propName

  // Normally only allowed for Arrays and types with index signatures

Every type is assignable to type any:

let storageLocation: any;

storageLocation = null;
storageLocation = true;
storageLocation = {};

Type any is assignable to every type:

function func(value: any) {
  const a: null = value;
  const b: boolean = value;
  const c: object = value;

With any we lose any protection that is normally given to us by TypeScript’s static type system. Therefore, it should only be used as a last resort, if we can’t use more specific types or unknown.

11.2.1 Example: JSON.parse()

The result of JSON.parse() depends on dynamic input, which is why the return type is any (I have omitted the parameter reviver from the signature):

JSON.parse(text: string): any;

JSON.parse() was added to TypeScript before the type unknown existed. Otherwise, its return type would probably be unknown.

11.2.2 Example: String()

The function String(), which converts arbitrary values to strings, has the following type signature:

interface StringConstructor {
  (value?: any): string; // call signature
  // ···

11.3 The top type unknown

The type unknown is a type-safe version of the type any. Whenever you are thinking of using any, try using unknown first.

Where any allows us to do anything, unknown is much more restrictive.

Before we can perform any operation on values of type unknown, we must first narrow their types via: