Краткое описание: any кажется безобидным: одна строчка —
Программист заходит в TypeScript.
Компилятор: ❌ Property name does not exist.
Новичок спустя четыре секунды:
const user: any = getUser();TypeScript: «Ладно. Делай что хочешь».
💀
Поздравляем. Ты только что отключил одну из главных причин вообще использовать TypeScript.

🤔 Почему вообще существует any?
Когда создавали TypeScript, разработчики понимали одну простую вещь: в мире уже существовали миллионы строк JavaScript.
Если бы всех заставили сразу типизировать абсолютно каждую переменную, функцию и объект, на TypeScript никто бы не перешёл. Поэтому появился any — своеобразный аварийный выход.
Он говорит компилятору:
Не проверяй это. Я сам разберусь.
Звучит уверенно.
На практике чаще означает:
Я устал бороться с типами.
💣 Что происходит после any
Посмотрим на простой пример:
const user: any = {
name: "Alex"
};
console.log(user.age.toUpperCase());Что скажет TypeScript?
Ничего.
Вообще ничего.
Хотя в этом коде сразу несколько проблем:
свойства
ageне существует;у
undefinedнет методаtoUpperCase();приложение упадёт уже во время выполнения.
Без any ошибка была бы найдена ещё до запуска проекта. Именно за это TypeScript и любят.
😂 Классический диалог разработчика с TypeScript
TypeScript: «Я нашёл потенциальную ошибку».
Разработчик:
value as anyTypeScript: «Понял. Тогда я пошёл».
🦠 any распространяется как вирус
Самая опасная особенность any в том, что он редко остаётся в одной переменной.
const api: any = fetchData();
const user = api.user;
const posts = user.posts;
const firstPost = posts[0];Теперь user — это any.
posts — тоже any.
firstPost — угадай что? Правильно, тоже any.
Одна переменная постепенно заражает весь код вокруг себя. В итоге TypeScript остаётся в проекте только технически, а фактически превращается обратно в JavaScript, но с дополнительными настройками и более долгой сборкой.
🔥 Почему проблемы появляются не сразу?
Самое неприятное — код с any может долго работать нормально.
Сегодня API возвращает:
{
"name": "Alex"
}Ты пишешь:
console.log(user.name);Через месяц бэкенд меняет структуру ответа:
{
"fullName": "Alex"
}TypeScript ничего не скажет, потому что данные были объявлены как any.
Зато пользователь увидит знакомое и очень вдохновляющее сообщение:
Cannot read properties of undefinedПосле этого начинается любимая игра разработчиков: «Найди баг, который появился три недели назад».
🛡️ Чем заменить any
Используй unknown, если тип действительно неизвестен
Если данные приходят извне и ты пока не знаешь их структуру, используй unknown.
const data: unknown = getData();Теперь TypeScript заставит сначала проверить значение:
if (typeof data === "string") {
console.log(data.toUpperCase());
}unknown тоже означает «я не знаю, что здесь находится», но в отличие от any не разрешает обращаться с данными как угодно.
any говорит: «Доверяй мне».
unknown говорит: «Сначала проверь».
Описывай интерфейсы
Вместо:
const user: any = getUser();лучше написать:
interface User {
id: number;
name: string;
email?: string;
}
const user: User = getUser();Теперь ты получаешь:
автодополнение в редакторе;
проверку существования свойств;
понятную структуру данных;
ошибки ещё до запуска программы.
Используй generics
Очень часто any появляется в универсальных функциях:
function getData(): any {
return fetchSomething();
}Вместо этого можно использовать generic:
function getData<T>(): T {
return fetchSomething() as T;
}Или передавать тип при вызове:
const user = getData<User>();Так данные не теряют типизацию на всём пути от функции до переменной.
Проверяй данные с API
Даже если TypeScript считает, что сервер возвращает объект User, настоящий сервер может отправить что угодно.
Поэтому для важных данных полезно использовать runtime-проверки, например библиотеки Zod, Valibot или собственные функции валидации.
function isUser(value: unknown): value is User {
return typeof value === "object"
&& value !== null
&& "id" in value
&& "name" in value;
}TypeScript проверяет код во время разработки. Валидация проверяет реальные данные во время работы приложения. Вместе они защищают намного лучше.
😅 Когда any всё-таки допустим?
Да, иногда any можно использовать. Например:
при миграции большого JavaScript-проекта на TypeScript;
при работе со старой библиотекой без нормальных типов;
во временном прототипе;
в очень сложном участке кода, который планируется типизировать позже;
при написании низкоуровневых универсальных утилит.
Но важно понимать: any — это не полноценное решение.
Это технический долг.
Сегодня он экономит пять минут. Через несколько месяцев может забрать несколько часов на поиск ошибки.
🚩 Признаки того, что any уже вышел из-под контроля
Стоит насторожиться, если:
anyвстречается почти в каждом файле;API-ответы нигде не типизированы;
разработчики регулярно используют
as any, чтобы убрать ошибку;интерфейсы существуют, но почти нигде не применяются;
после рефакторинга появляется много runtime-ошибок;
автодополнение в редакторе почти бесполезно.
В такой ситуации TypeScript уже не защищает проект. Он просто присутствует рядом.
🧹 Как постепенно избавиться от any
Необязательно переписывать весь проект за один день.
Включи правило ESLint
@typescript-eslint/no-explicit-any.Замени самые простые
anyна конкретные типы.В местах с неизвестными данными используй
unknown.Типизируй ответы API.
Добавь generics в универсальные функции.
Используй временные комментарии с объяснением, почему
anyпока необходим.
Например:
// TODO: заменить после обновления типов библиотеки
const legacyValue: any = oldLibrary.getValue();Так хотя бы понятно, что это осознанный компромисс, а не постоянная архитектура проекта.
📱 Где научиться TypeScript без бесконечного копирования
Если хочется не просто запоминать синтаксис, а действительно понимать, зачем нужны типы, интерфейсы, generics и проверки данных, попробуй приложение Кодик.
В нём обучение программированию построено вокруг практики:
💻 интерактивные задания;
🧩 упражнения с постепенным усложнением;
🚀 проверка кода прямо в приложении;
🎯 закрепление тем на практике;
📚 обучение в удобном темпе.
Это помогает не просто посмотреть урок, а самому написать код, получить обратную связь и понять, где именно появилась ошибка.
А ещё у Кодика есть сообщество в Telegram, где выходят полезные посты, небольшие разборы, викторины, советы и интересные факты о разработке. Это удобный способ регулярно повторять программирование и не выпадать из темы даже в дни, когда на полноценное занятие нет времени.
🎯 Главное правило
Перед тем как написать:
anyостановись на секунду и спроси себя:
Я действительно не знаю тип или мне просто лень его описывать?
В большинстве случаев честный ответ оказывается вторым. 😄
any — это не просто ещё один тип.
Это кнопка:
Я временно отключаю защиту своего проекта.
Иногда нажать её можно. Но чем реже ты это делаешь, тем меньше неожиданных ошибок прилетает в прод и тем спокойнее проходят рефакторинги.
Потому что хороший TypeScript-код — это не код без ошибок компилятора.
Это код, в котором компилятору разрешили делать свою работу.
