← Назад к вопросам

В чем разница между any и unknown типом?

1.3 Junior🔥 171 комментариев
#TypeScript

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

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

Оба этих типа представляют переменную, которая может иметь значение любого типа. Однако они работают совершенно по-разному, и unknown — это безопаснее.

Главное отличие

  • any — это эскейп из системы типов (побег). TypeScript перестаёт проверять типы.
  • unknown — это тип, который говорит: "я не знаю тип, но я буду проверять перед использованием" (type-safe).

any: полная свобода (опасно)

const x: any = "hello";

// Все эти операции работают БЕЗ ошибок, хотя они неправильные!
x.toUpperCase();      // работает
x.toLowerCase();      // работает
x.toExponential();    // TypeScript не ругается (но ошибка в runtime!)
x.push(1);            // TypeScript не проверяет
x.map(char => char);  // TypeScript пропускает

// Функция может вернуть что угодно
function parseJson(json: string): any {
  return JSON.parse(json);
}

const result = parseJson('{"name": "Alice"}');
const name: string = result.name;     // TypeScript не ругается
const age: number = result.age;       // TypeScript не ругается

unknown: безопасность (правильно)

const x: unknown = "hello";

// Все эти операции выдают ошибку TS!
x.toUpperCase();      // ошибка: Object is of type unknown
x.toLowerCase();      // ошибка
x.toExponential();    // ошибка
x.push(1);            // ошибка
x.map(char => char);  // ошибка

// Нужно сначала проверить тип!
if (typeof x === "string") {
  x.toUpperCase(); // теперь TypeScript знает, что это string
}

if (typeof x === "number") {
  x.toExponential(); // теперь TypeScript знает, что это number
}

Практический пример: функция с неизвестным типом

С any (плохо):

function processData(data: any) {
  // Никаких ошибок типов!
  const length = data.length;      // может быть undefined
  const mapped = data.map(x => x); // может упасть в runtime
  const result = data.toFixed(2);  // может упасть если не число
  
  return result;
}

processData("hello");   // работает (но может крешиться)
processData(123);        // работает (но может крешиться)
processData({});         // работает (но может крешиться)

С unknown (хорошо):

function processData(data: unknown) {
  // Нужно проверять тип!
  
  if (typeof data === "string") {
    const length = data.length; // safe
    return data.toUpperCase();  // safe
  }
  
  if (typeof data === "number") {
    return data.toFixed(2);     // safe
  }
  
  if (Array.isArray(data)) {
    return data.map(x => x);    // safe
  }
  
  throw new Error(`Unexpected data type: ${typeof data}`);
}

processData("hello");   // работает
processData(123);        // работает
processData({});         // выбросит ошибку при разработке

Type Guards для unknown

// Простые type guards
function handleUnknown(value: unknown) {
  if (typeof value === "string") {
    console.log(value.length);
  } else if (typeof value === "number") {
    console.log(value.toFixed(2));
  } else if (Array.isArray(value)) {
    console.log(value.length);
  }
}

// Продвинутые type guards
function isString(value: unknown): value is string {
  return typeof value === "string";
}

function isNumber(value: unknown): value is number {
  return typeof value === "number" && !isNaN(value);
}

function isObject(value: unknown): value is Record<string, unknown> {
  return value !== null && typeof value === "object" && !Array.isArray(value);
}

const data: unknown = getData();

if (isString(data)) {
  console.log(data.toUpperCase());
} else if (isNumber(data)) {
  console.log(data.toFixed(2));
} else if (isObject(data)) {
  console.log(data.name);
}

JSON.parse пример

С any:

const user: any = JSON.parse(jsonString);
const age: number = user.age; // может быть undefined!
const name: string = user.name; // может быть undefined!

age.toFixed(2); // runtime ошибка!
name.toUpperCase(); // runtime ошибка!

С unknown:

interface User {
  age: number;
  name: string;
}

function parseUser(jsonString: string): unknown {
  return JSON.parse(jsonString);
}

const user: unknown = parseUser(jsonString);

// Нужно проверить структуру
if (
  user !== null &&
  typeof user === "object" &&
  "age" in user &&
  "name" in user
) {
  const typed = user as User;
  console.log(typed.age.toFixed(2));
  console.log(typed.name.toUpperCase());
} else {
  console.error("Invalid user data");
}

Таблица сравнения

Аспектanyunknown
Тип проверкаОтключенаВключена
Можно присвоить что угодноДаДа
Можно использовать что угодноДаНет, нужна проверка
БезопасностьОпасноБезопасно
Требует type guardsНетДа
Рекомендуется использоватьНет (избегать)Да (когда не знаешь тип)

Когда что использовать

Используй unknown:

  • Когда получаешь данные от API
  • Когда парсишь JSON
  • Когда получаешь результат JSON.parse()
  • Когда функция может вернуть разные типы
  • Когда нужна максимальная типизация

Используй any (редко):

  • Когда мигрируешь код из JavaScript
  • Когда работаешь с третьей библиотекой без типов
  • Когда нужна быстрая прототипизация

Конфигурация TypeScript

{
  "compilerOptions": {
    "strict": true,
    "noImplicitAny": true,
    "noImplicitThis": true
  }
}

Резюме

  • any — отключает проверку типов (избегай!)
  • unknown — включает проверку типов и требует type guards (используй!)
  • unknown безопаснее и проверяет типы на этапе разработки
  • Правило: неизвестный тип = unknown, а не any
  • Всегда добавляй type guards для unknown перед использованием

Для интервью: я предпочитаю unknown вместо any, потому что это заставляет меня явно обрабатывать разные типы данных, что делает код безопаснее и предсказуемее.

В чем разница между any и unknown типом? | PrepBro