Разница между any и unknown

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

Тренажер по TypeScript

Два специальных типа в TypeScriptany и unknown — часто вызывают путаницу, но разница между ними критична для безопасности.

any — это «выключатель» проверки типов. Он позволяет делать с переменной что угодно, что часто приводит к ошибкам в рантайме. Это плохая практика, если используется без веской причины.

unknown — это безопасный аналог any. Переменная этого типа может хранить любое значение, но TypeScript запретит вам использовать её методы или свойства, пока вы явно не проверите её тип (сужение типа).

В этом уроке мы разберем:

  • Почему unknown лучше, чем any.
  • Как перевести небезопасный код на unknown.
  • Способы сужения типа unknown до строки, числа или объекта.
Список тем

1. Any vs Unknown

id: 40633_any_unknown_compare_features

В левой колонке перечислены характеристики поведения типов в TypeScript, а в правой — указано, к какому типу (any, unknown или к обоим) относится каждая характеристика. Сопоставьте каждое описание поведения с соответствующим типом или категорией. Это поможет понять ключевые различия между any и unknown при работе с динамическими данными.

Сопоставьте строки в правой(нижней) части с соответствующими строками в левой(верхней) по порядковому номеру
Отключает проверку типов компилятором
Требует сужения типа перед использованием значения
Можно присвоить значение любого типа
Позволяет вызывать любые методы без ошибок компиляции
Нельзя присвоить другой переменной без проверки типа
Оба типа
any
unknown
any
unknown
Сообщения
Проверить
Показать подсказку

2. Повышение безопасности

id: 40633_any_unknown_replace_safe

В этом задании вам нужно повысить типобезопасность функции, обрабатывающей ответ от сервера. Замените тип `any` на более строгий тип, который заставляет выполнять проверки перед использованием значения. Это поможет избежать случайных ошибок типизации. Вставьте правильный тип в отмеченное место, чтобы код стал безопаснее, но остался рабочим.

Заполните пропуски
function processServerResponse(data: input1S): string {
    // Предполагаем, что data - это объект с полем message типа string
    if (typeof data === 'object' && data !== null && 'message' in data) {
        return data.message;
    }
    return 'Ошибка: неверный формат данных';
}
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

3. Небезопасные места

id: 40633_any_unknown_click_target_unsafe

В представленном фрагменте кода TypeScript используются переменные с типами `any` и `unknown`. Внимательно изучите код и отметьте все места, где вызывается метод или обращение к свойству, которое компилятор TypeScript разрешает исключительно из-за использования типа `any` (то есть где отсутствует реальная проверка типа, которая потребовалась бы для `unknown`). Не отмечайте строки с объявлениями переменных, проверками типов (например, `typeof`), вызовами методов у переменной `unknown` после сужения типа или другие части кода, не соответствующие условию.

Кликните по всем фрагментам, которые подходят под условие задания.
let valueAny: any = 'Hello';
let valueUnknown: unknown = 123;

// Небезопасные операции для any
{{valueAny.toUpperCase()~|~t1}};
{{valueAny.someMethod()~|~t2}};
{{valueAny.property~|~t3}};

// Проверка типа для unknown
if (typeof valueUnknown === 'number') {
    {{valueUnknown.toFixed(2)~|~d1}}; // Безопасный вызов после сужения типа
}

// Еще один небезопасный вызов для any
{{valueAny.anotherMethod()~|~t4}};

// Обращение к свойству у объекта с типом any
let obj: any = { x: 10 };
console.log({{obj.x~|~t5}});

// Вызов метода у строкового литерала (тип известен, не any)
{{'test'.toUpperCase()~|~d2}};
Сообщения
Проверить
Показать подсказку

4. Валидация JSON

id: 40633_any_unknown_build_validator

Из предложенных строк соберите корректную функцию на TypeScript, которая принимает аргумент типа unknown, проверяет, является ли он строкой, и если да, то парсит её как JSON, возвращая результат. Если аргумент не строка, функция должна возвращать null. В решении не должно быть лишних строк, не влияющих на логику валидации. Задание направлено на понимание разницы между типами any и unknown и их использование в контексте проверки типов.

Перетяните в правильном порядке строки из одного блока в другой
function parseJson(input: unknown): any {
  if (typeof input === 'string') {
    const parsed = JSON.parse(input);
    return parsed;
  }
  return null;
}
  let x: any = input;
  if (typeof input === 'number') {
    console.log(input);
Сообщения
Проверить
Показать решение на 3 сек.
Показать подсказку

5. Компиляция кода

id: 40633_any_unknown_predict_compile

Проанализируйте два фрагмента кода на TypeScript. Один использует тип `any`, другой — `unknown`. Оба пытаются получить доступ к свойству `name` у переменной. Определите, какой из примеров вызовет ошибку компиляции (ошибку проверки типов) в TypeScript.

Выберите правильный вариант ответа

Пример 1 (с типом any):

let data: any = { name: "Alice" };
console.log(data.name); // Прямой доступ к свойству

Пример 2 (с типом unknown):

let data: unknown = { name: "Bob" };
console.log(data.name); // Прямой доступ к свойству
Сообщения
Проверить
Показать подсказку

6. Алгоритм безопасного доступа

id: 40633_any_unknown_analyze_steps

Проанализируйте TypeScript-код сверху и восстановите последовательность логических шагов выполнения программы. Шаги снизу перемешаны — расставьте их в правильном порядке, чтобы отразить, как программа безопасно обрабатывает данные типа unknown, проверяет их тип и выполняет соответствующую операцию.

function processValue(value: unknown): string {
  if (typeof value === 'string') {
    return `String: ${value.toUpperCase()}`;
  } else if (typeof value === 'number') {
    return `Number: ${value.toFixed(2)}`;
  } else {
    return 'Unsupported type';
  }
}

const result = processValue('hello');
console.log(result);
Расположите элементы в логичном порядке
Проверка типа аргумента с помощью typeof (определяется как 'string')
Вывод результата в консоль
Формирование строки результата: 'String: HELLO'
Возврат результата из функции
Завершение работы функции (ветка else не выполняется, так как тип string)
Выполнение операции для строки: применение метода toUpperCase()
Вызов функции processValue с аргументом 'hello' (тип unknown)
Сообщения
Проверить
Показать подсказку

7. Типы данных

id: 40633_any_unknown_highlight_types

В объявлении функции на TypeScript разметьте аннотации типов для параметров и возвращаемого значения. Для каждого выделенного фрагмента укажите, является ли он типом `any`, `unknown` или `void`. Обратите внимание на расположение двоеточий и ключевых слов типов.

Кликните по каждому выделенному фрагменту и выберите для него подходящий тип из списка под текстом.
function process(data: {{any~|~t1}}, input: {{unknown~|~t2}}): {{void~|~t3}} {
  // ...
}
Тип any
Тип void
Тип unknown
Сообщения
Проверить
Показать подсказку

8. Type Assertion

id: 40633_any_unknown_sequencing_conversion

Перед вами строки TypeScript-кода, демонстрирующие работу с типом unknown и приведением типов (type assertion). Переменная unknown требует проверки типа перед использованием. Строки перемешаны. Восстановите правильную последовательность кода, где сначала объявляется переменная типа unknown, затем выполняется проверка её типа с помощью typeof, и только после этого, с использованием утверждения типа (as), переменная приводится к конкретному типу для дальнейших операций. Обратите внимание, что прямое приведение типов (as) считается плохой практикой, но в данном примере используется для демонстрации.

Расставьте строки в правильном порядке
let value: unknown = 'Hello, TypeScript!';
    let length: number = (value as string).length;
}
    console.log(length);
if (typeof value === 'string') {
Сообщения
Проверить
Показать подсказку

TypeScript: компиляция и запуск

id: 40633_compiler

Этот пример показывает разницу между any и unknown: с any TypeScript «верит вам на слово», а с unknown заставляет сначала проверить тип. Попробуйте менять значения переменных (строку, число, объект, null), чтобы увидеть, где код ломается в рантайме и где компилятор помогает заранее. Поэкспериментируйте: раскомментируйте строки с ошибками компиляции и сравните поведение с any. Добавляйте свои функции-проверки (type guard) и расширяйте обработку, чтобы безопасно доставать нужные поля и вызывать методы.

TS
Запустить тренажёр (TypeScript)
НайтиКурс.Ру