Skip to main content

unknown vs any

1. Що робить unknown

unknown - це безпечна альтернатива any. Він каже: "я не знаю, що це за значення, тому ти повинен довести його тип, перш ніж використовувати".

Приклад:

javascript
let value: unknown = "hello"; value.toUpperCase(); // Помилка: Object is of type 'unknown' if (typeof value === "string") { value.toUpperCase(); // OK, тип доведено }

На відміну від any, TypeScript не дозволяє робити нічого, поки ти не уточниш (звузиш) тип. Саме це робить unknown безпечним за замовчуванням.


2. Чому unknown безпечніший, ніж any

Поведінкаanyunknown
Можна викликати методи без перевіркиТакНі
Можна присвоювати в інші типиБез обмеженьЛише після перевірки
IDE підказує властивостіНіНі (до перевірки)
Вимагає type narrowingНіТак
Може призвести до рантайм-помилокЧастоТільки якщо обійти перевірки

Приклад:

javascript
let a: any = "hello"; let u: unknown = "hello"; a.foo(); // TS пропустить -> впаде в runtime u.foo(); // TS не дозволить -> безпечно

3. Чому unknown все ще можна використовувати погано

Хоча unknown безпечніший, все залежить від того, що ти з ним робиш. Якщо ти насильно "ламаєш" типізацію, unknown перестає бути безпечним.


Помилка 1: Примусове приведення через as

javascript
let data: unknown = "Hello"; const num = data as number; // примусове приведення console.log(num.toFixed(2)); // runtime помилка

Приведення (as number) обходить усі перевірки TS. Тобто - ти знову повернувся до поведінки any.

Висновок: unknown безпечний, поки ти не змушуєш TS "повірити тобі на слово".


Помилка 2: Широке поширення unknown

Якщо ти повертаєш unknown з функцій або зберігаєш його в структурах даних, типова система втрачає контекст.

Приклад:

javascript
function parseJSON(str: string): unknown { return JSON.parse(str); } const result = parseJSON('{"id":1,"name":"Alex"}'); // result: unknown console.log(result.name); // помилка, поки не перевіриш

Це безпечно, але незручно - ти змушений усюди вручну звужувати типи. Якщо таких значень багато, це призводить до типового хаосу.


Помилка 3: Занадто узагальнені типи функцій

Якщо в API-функції все оголошено як unknown, ти втрачаєш корисність типізації - IDE більше не знає, що повертає функція.

javascript
function getUser(): unknown { return { name: "Alex", age: 30 }; } const user = getUser(); user.name; // Помилка - TS не знає, що там об'єкт

Код безпечний, але марний: TS захищає від помилок, але не допомагає розробляти.


Помилка 4: Присвоєння unknown без уточнення

javascript
let data: unknown = 42; let str: string = data; // Помилка: Type 'unknown' is not assignable to type 'string'

Добре, що TypeScript ловить це, але якщо ти напишеш as string, все одно зламається логіка:

javascript
let str = data as string; console.log(str.toUpperCase()); // runtime помилка

4. Як правильно використовувати unknown

Використовуй unknown як бар'єр безпеки - на межах із зовнішніми даними, де ти не можеш довіряти типам (API, JSON, введення користувача).

Приклад:

javascript
function parse<T>(json: string): T { const data: unknown = JSON.parse(json); if (isUser(data)) { return data; // TS тепер впевнений } throw new Error("Invalid user data"); }

Тут:

  • unknown -> безпечний старт
  • isUser() -> type guard
  • T -> повертаємо типізоване значення

5. Коли unknown кращий за any, а коли - ні

СитуаціяКраще unknownКраще any
При отриманні даних з APIТакНі
При швидкому дебагу або тимчасовому кодіМожна, але громіздкоТак (тимчасово)
При написанні універсальних функційТак (звужуй тип пізніше)Ні
У legacy-коді, де немає часу на суворі перевіркиНезручноТимчасово допустимо
У публічних бібліотекахТак (зовнішнє введення - unknown)Ні

6. Правильний приклад з перевірками

javascript
function isUser(value: unknown): value is { id: number; name: string } { return ( typeof value === "object" && value !== null && "id" in value && "name" in value ); } const data: unknown = JSON.parse('{"id":1,"name":"Alex"}'); if (isUser(data)) { console.log(data.name.toUpperCase()); // безпечно } else { console.error("Invalid user"); }

Тут unknown виконує своє завдання - захищає від невірного типу, поки ти не доведеш протилежне.


7. Принципова різниця у філософії

anyunknown
Філософія"Я знаю, що роблю""Я поки не знаю, що це"
Безпекавідсутнямаксимальна
Застосуваннятимчасові рішення, legacyзовнішні дані, API, динаміка
Перевірка типіввимкненаобов'язкова
Порушує контракт типівлегколише через as

Підсумок

ПитанняВідповідь
Чому unknown безпечніший?Він змушує тебе перевірити тип перед використанням.
Чому може бути небезпечним?Якщо обійти перевірки через as або використовувати занадто широко, втрачається сенс типізації.
Де доречний?На межах застосунку: парсинг JSON, введення користувача, непередбачувані API.
Головна ідеяunknown - це "безпечне невідоме". Ти не можеш використати значення, поки не доведеш, що воно потрібного типу.

Просто запам'ятай:

any - "я знаю краще за TypeScript". unknown - "TypeScript, допоможи мені переконатися".

Але якщо ти сам "обманеш" компілятор (через as), то unknown перестане бути безпечним і стане звичайним any під маскою.

Коротка відповідь

Для співбесіди
Premium

Коротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.