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

Как относишься к any в коде?

2.0 Middle🔥 121 комментариев
#Soft Skills и рабочие процессы

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

🐱
claude-haiku-4.5PrepBro AI3 апр. 2026 г.(ред.)

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

Как относишься к any в коде?

Личное отношение к any в TypeScript категорично: он является одним из главных врагов надежного и поддерживаемого кода. Это не значит, что any не нужен совсем, но его использование должно быть исключением, а не нормой.

Почему any опасен

Типография в TypeScript создана для предотвращения ошибок на этапе разработки. Когда вы пишете any, вы говорите компилятору: я сдаюсь, не проверяй это. Результат:

// Классический случай
function processData(data: any) {
  return data.toUpperCase(); // Может упасть, если data - число
}

const result = processData(123); // TypeScript не ругается, но код упадет в runtime

Типичные проблемы:

  1. Потеря type-safety - вы теряете помощь IDE (автодополнение, рефакторинг)
  2. Скрытые баги - ошибки проявляются в production
  3. Сложнее поддерживать - новые разработчики не понимают, что ожидается
  4. Нарушает контракт между модулями - нет гарантии на данные

Правильная альтернатива: unknown

unknown - это правильный выбор когда тип неизвестен. Это то же самое, что any, но безопасно:

// Правильно - unknown
function processData(data: unknown) {
  // TypeScript требует type guard перед использованием
  if (typeof data === "string") {
    return data.toUpperCase();
  }
  throw new Error("Expected string, got " + typeof data);
}

const result = processData(123); // Error: Expected string, got number

Отличие: с unknown вы ДОЛЖНЫ проверить тип перед использованием. С any - не нужно, что опасно.

Type Guards для unknown

// Пример 1: простая проверка типа
function isString(value: unknown): value is string {
  return typeof value === "string";
}

function process(data: unknown) {
  if (isString(data)) {
    console.log(data.length); // TypeScript знает, что это string
  }
}

// Пример 2: проверка объекта
interface User {
  id: number;
  name: string;
}

function isUser(obj: unknown): obj is User {
  return (
    typeof obj === "object" &&
    obj !== null &&
    "id" in obj &&
    "name" in obj &&
    typeof obj.id === "number" &&
    typeof obj.name === "string"
  );
}

Когда any все же допустим

1. Интеграция с нетипизированными библиотеками

const $ = require("jquery") as any; // Старая библиотека

2. Временная заглушка при миграции

// TODO: Типизировать после миграции модуля X
function legacyFunction(data: any): string {
  return data.stringify();
}

Как я бы писал типобезопасный код

// Плохо
function fetchUser(id: any): any {
  return fetch(`/api/users/${id}`).then((r: any) => r.json());
}

// Хорошо
interface User {
  id: number;
  name: string;
  email: string;
}

function fetchUser(id: number): Promise<User> {
  return fetch(`/api/users/${id}`)
    .then((response) => {
      if (!response.ok) throw new Error(`HTTP ${response.status}`);
      return response.json();
    })
    .then((data): User => {
      if (
        typeof data === "object" &&
        typeof data.id === "number" &&
        typeof data.name === "string"
      ) {
        return data;
      }
      throw new Error("Invalid user data");
    });
}

Включайте strict режим

В tsconfig.json установите strict: true:

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

Правило для team-а

Я бы предложил:

  1. Запрещаем any по умолчанию через tsconfig.json
  2. Используем unknown вместо any для неизвестных типов
  3. Для нетипизированных библиотек создаем минимальные type definitions
  4. Исключения с комментарием - если всё же нужен any, обязателен комментарий

Итоговая позиция

any - это поражение в войне за типобезопасность. Если вы используете TypeScript, используйте его правильно. Цена 10 минут на написание правильных типов - это ничто по сравнению с поиском багов в production из-за неправильного типирования.