unknown проти any
1. Що робить unknown
unknown- це безпечна альтернативаany. Він каже: «я не знаю, що це за значення, тому ти маєш довести його тип, перш ніж використовувати».
Приклад:
let value: unknown = "hello";
value.toUpperCase(); // Помилка: Object is of type 'unknown'
if (typeof value === "string") {
value.toUpperCase(); // Ок, тип доведено
}На відміну від any, TypeScript не дозволяє робити нічого,
поки ти не уточниш (звузиш) тип.
Саме це робить unknown безпечним за умовчанням.
2. Чому unknown безпечніший, ніж any
| Поведінка | any | unknown |
|---|---|---|
| Можна викликати методи без перевірки | Так | Ні |
| Можна присвоювати іншим типам | Без обмежень | Тільки після перевірки |
| IDE підказує властивості | Ні | Ні (до перевірки) |
| Потребує type narrowing | Ні | Так |
| Може призвести до runtime-помилок | Часто | Тільки якщо обійти перевірки |
Приклад:
let a: any = "hello";
let u: unknown = "hello";
a.foo(); // TS пропустить → впаде в runtime
u.foo(); // TS не дозволить → безпечно3. Чому unknown все ще можна використовувати погано
Хоча unknown безпечніший, все залежить від того, що ти з ним робиш.
Якщо ти насильно «ламаєш» типізацію, unknown перестає бути безпечним.
Помилка 1: Примусове приведення через as
let data: unknown = "Hello";
const num = data as number; // примусове приведення
console.log(num.toFixed(2)); // runtime помилкаПриведення (as number) обходить усі перевірки TS.
Тобто ти знову повернувся до поведінки any.
Висновок:
unknown безпечний, поки ти не змушуєш TS «повірити тобі на слово».
Помилка 2: Широке розповсюдження unknown
Якщо ти повертаєш unknown з функцій або зберігаєш його в структурах даних,
типова система втрачає контекст.
Приклад:
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 більше не знає, що повертає функція.
function getUser(): unknown {
return { name: "Alex", age: 30 };
}
const user = getUser();
user.name; // Помилка - TS не знає, що там об’єктКод безпечний, але марний: TS захищає від помилок, але не допомагає розробляти.
Помилка 4: Присвоєння unknown без уточнення
let data: unknown = 42;
let str: string = data; // Помилка: Type 'unknown' is not assignable to type 'string'Добре, що TypeScript ловить це,
але якщо ти напишеш as string, логіка все одно зламається:
let str = data as string;
console.log(str.toUpperCase()); // runtime помилка4. Як правильно використовувати unknown
Використовуй unknown як бар’єр безпеки -
на межах із зовнішніми даними, яким ти не можеш довіряти (API, JSON, користувацький ввід).
Приклад:
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 guardT→ повертаємо типізоване значення
5. Коли unknown кращий за any, а коли - ні
| Ситуація | Краще unknown | Краще any |
|---|---|---|
| При отриманні даних з API | Так | Ні |
| При швидкому налагодженні або тимчасовому коді | Можна, але громіздко | Так (тимчасово) |
| При написанні універсальних функцій | Так (звужуй тип пізніше) | Ні |
| У legacy-коді, де немає часу на строгі перевірки | Незручно | Тимчасово припустимо |
| У публічних бібліотеках | Так (зовнішній ввід - unknown) | Ні |
6. Правильний приклад із перевірками
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. Принципова різниця у філософії
any | unknown | |
|---|---|---|
| Філософія | «Я знаю, що роблю» | «Я поки не знаю, що це» |
| Безпека | відсутня | максимальна |
| Застосування | тимчасові рішення, legacy | зовнішні дані, API, динаміка |
| Перевірка типів | вимкнена | обов’язкова |
| Порушує контракт типів | легко | лише через as |
Підсумок
| Питання | Відповідь |
|---|---|
Чому unknown безпечніший? | Він змушує тебе перевірити тип перед використанням. |
| Чому може бути небезпечний? | Якщо обійти перевірки через as або використовувати занадто широко, губиться сенс типізації. |
| Де доречний? | На межах застосунку: парсинг JSON, введення користувача, непередбачувані API. |
| Головна ідея | unknown - це «безпечне невідоме». Ти не можеш використати значення, поки не доведеш, що воно потрібного типу. |
Просто запам’ятай:
any- «я знаю краще за TypeScript».unknown- «TypeScript, допоможи мені пересвідчитися».Але якщо ти сам «обманеш» компілятор (через
as), тоunknownперестане бути безпечним і стане звичайнимanyпід маскою.
Коротка відповідь
Для співбесідиКоротка відповідь допоможе вам впевнено відповідати на цю тему під час співбесіди.