Categories
TypeScript

TypeScript any and unknown Types

Spread the love

In TypeScript, there’re 2 data types that can hold anything.

They’re the any and unknown types.

Since they have different names, they’re different.

In this article, we’ll look at the difference between them and what can we do with them.

The any Type

The any type variable lets us assign anything to it.

If it’s used as a parameter, then we can pass in anything.

For example, we can write:

function func(value: any) {
  const foo = 5 * value;
  const bar = value[1];
}

The TypeScript compiler doesn’t restrict what we can do with a variable or parameter that has an any type.

If we have a variable, we can assign anything to it.

For instance, we can write:

let bar: any;

bar = null;
bar = true;
bar = {};

We can assign anything to a variable with the any type.

Also, we can assign an any variable to variables, with any type:

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

A real example would be JSON.parse . Its signature in TypeScript’s type definition is:

JSON.parse(text: string): any;

The unknown type doesn’t exist yet in TypeScript with it’s added to the type definition, so the any type is used as the return type.

The unknown type is a better alternative to any for typing things that don’t have a known structure.

The unknown Type

The unknown type is a safer version of any .

This is because any lets us do anything, but unknown has more restrictions.

Before we can do anything with a value with an unknown type, we’ve to make the type known first by using type assertions, equality, type guards, or assertion functions.

To add type assertions, we can use the as keyword.

For example, we can write:

function func(value: unknown) {
  return (value as number).toFixed(2);
}

Since we casted the value parameter to a number with as , we can call the toFixed method with it to round the number.

The TypeScript compiler can also determine the data type with equality comparison.

For example, we can write:

function func(value: unknown) {
  if (value === 123)
    const rounded =  value.toFixed(2);
  }
}

We check if value is 123.

This way, if it is, then the TypeScript compiler knows it’s a number.

So we can call toFixed on it.

We can do the same with type guards.

To use them, we use the typeof operator to check the type.

So we can write:

function func(value: unknown) {
  if (typeof value === 'number')
    const rounded =  value.toFixed(2);
  }
}

and the compiler will also know that value is a number.

We can also use assertion functions to do the same thing.

For example, we can write:

function func(value: unknown) {
  assertNum(value);
  const rounded = value.toFixed(2);
}

function assertNum(arg: unknown): asserts arg is number {
  if (typeof arg !== 'number') {
    throw new TypeError('not a number');
  }
}

We create a assertNum function to check if arg is a number.

If it’s not, then an exception is thrown.

We then call it in our func function before doing any operation.

This way, the compiler also knows value is a number.

Conclusion

The any type is too flexible for most cases.

unknown type lets us store anything, but we’ve to determine the type of it before doing anything.

By John Au-Yeung

Web developer specializing in React, Vue, and front end development.

Leave a Reply

Your email address will not be published. Required fields are marked *