В TypeScript есть 2 типа данных, которые могут содержать что угодно.

Это типы any и unknown.

Поскольку у них разные имена, они разные.

В этой статье мы рассмотрим разницу между ними и рассмотрим, что с ними делать.

Любой тип

Переменная типа any позволяет нам присвоить ей что угодно.

Если он используется в качестве параметра, мы можем передать что угодно.

Например, мы можем написать:

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

Компилятор TypeScript не ограничивает то, что мы можем делать с переменной или параметром, имеющим тип any.

Если у нас есть переменная, мы можем присвоить ей что угодно.

Например, мы можем написать:

let bar: any;
bar = null;
bar = true;
bar = {};

Мы можем назначить что угодно переменной с типом any.

Кроме того, мы можем присвоить переменную any переменным любого типа:

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

Реальный пример - JSON.parse. Его подпись в определении типа TypeScript:

JSON.parse(text: string): any;

Тип unknown еще не существует в TypeScript, он добавлен в определение типа, поэтому тип any используется в качестве возвращаемого типа.

Тип unknown - лучшая альтернатива any для набора текста, структура которого неизвестна.

The unknown Type

Тип unknown является более безопасной версией any.

Это потому, что any позволяет нам делать что угодно, но unknown имеет больше ограничений.

Прежде чем мы сможем что-либо сделать со значением с типом unknown, мы должны сначала сделать этот тип известным, используя утверждения типа, равенство, защиту типа или функции утверждения.

Чтобы добавить утверждения типа, мы можем использовать ключевое слово as.

Например, мы можем написать:

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

Поскольку мы преобразовали параметр value в число с as, мы можем вызвать метод toFixed с ним для округления числа.

Компилятор TypeScript также может определять тип данных с помощью сравнения на равенство.

Например, мы можем написать:

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

Мы проверяем, равно ли value 123.

Таким образом, если это так, то компилятор TypeScript знает, что это число.

Так что мы можем вызвать toFixed.

То же самое можно сделать и с охранниками типа.

Чтобы использовать их, мы используем оператор typeof для проверки типа.

Итак, мы можем написать:

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

и компилятор также будет знать, что value - это число.

Мы также можем использовать функции утверждения, чтобы сделать то же самое.

Например, мы можем написать:

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');
  }
}

Мы создаем assertNum функцию, чтобы проверить, является ли arg числом.

Если это не так, создается исключение.

Затем мы вызываем его в нашей func функции перед выполнением какой-либо операции.

Таким образом, компилятор также знает, что value - это число.

Вывод

Тип any слишком гибкий для большинства случаев.

unknown type позволяет нам хранить что угодно, но мы должны определить его тип, прежде чем что-либо делать.

Понравилась эта статья? Если да, то получите больше похожего контента, подписавшись на наш канал YouTube в Decoded!