Комментарии (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");
}
Таблица сравнения
| Аспект | any | unknown |
|---|---|---|
| Тип проверка | Отключена | Включена |
| Можно присвоить что угодно | Да | Да |
| Можно использовать что угодно | Да | Нет, нужна проверка |
| Безопасность | Опасно | Безопасно |
| Требует 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, потому что это заставляет меня явно обрабатывать разные типы данных, что делает код безопаснее и предсказуемее.