Как @ts-ignore работает для блока: 3 способа в TypeScript

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Тишина в редакторе: зачем нам блокировать TypeScript?

Каждый, кто писал на TypeScript хотя бы неделю, сталкивался с ситуацией, когда компилятор начинает «орать» на, казалось бы, рабочий код. Вы уверены, что логика верна, но tsc или IDE подсвечивают красным каждую вторую строку. Особенно больно, когда это происходит внутри одного блока: цикла, условия или функции.

Стандартный // @ts-ignore работает только для следующей строки. А что, если нужно «заткнуть» компилятор на 10–15 строк сразу? Копировать один и тот же комментарий перед каждой строкой — путь в никуда. Это не только засоряет код, но и делает его нечитаемым.

В этой статье мы разберем три реальных подхода, как применить @ts-ignore для целого блока в TypeScript. Вы узнаете, когда каждый из них уместен, а когда лучше вообще отказаться от подавления ошибок. Поехали!

Проблема: @ts-ignore работает только на одну строку

Давайте начнем с базового примера. Представьте, что вы работаете с динамическими данными из API, где типы могут меняться. У вас есть блок кода, который точно выполнится, но TypeScript ругается на каждое обращение к свойству.

// Пример: парсинг ответа от ненадёжного API
const data: any = { user: { name: 'Alice', age: 30 } };

// @ts-ignore
console.log(data.user.name); // OK, но только одна строка

// Следующая строка снова вызовет ошибку, если не добавить // @ts-ignore
// console.log(data.user.age); // Error: Property 'age' does not exist on type 'object'

Писать // @ts-ignore перед каждой строкой — плохая практика. Это увеличивает объём кода, усложняет рефакторинг и скрывает реальные ошибки. Но есть и хорошие новости: TypeScript (начиная с версии 3.9) и сообщество придумали несколько элегантных решений.

Подход 1: @ts-nocheck — грубая сила для целого файла

Самый простой, но и самый радикальный способ — добавить // @ts-nocheck в начало файла. Это полностью отключает проверку типов для всего файла. Но нам нужен блок, а не весь файл. Однако, есть хитрость: можно вынести проблемный блок в отдельный файл и импортировать его.

Плюсы:

  • Мгновенно решает проблему.
  • Подходит для легаси-кода, который вы планируете переписать позже.

Минусы:

  • Отключает все проверки типов в файле. Вы можете пропустить реальные баги.
  • Не подходит для больших проектов с строгими правилами линтинга.
  • Создаёт «чёрные ящики» из кода.
// bad.ts — файл с отключённой проверкой
// @ts-nocheck
export function processData(data: any) {
    const result = data.user.name + ' is ' + data.user.age;
    return result; // Ошибки не будет, даже если data — null
}

Когда использовать: Только для временных скриптов или унаследованного кода, который вы переписываете. Никогда не используйте в продакшене без явной пометки TODO.

Подход 2: ts-expect-error — умный аналог @ts-ignore

Начиная с TypeScript 3.9, появилась директива // @ts-expect-error. Она работает почти как @ts-ignore, но с одним важным отличием: если ошибки нет, TypeScript выдаст предупреждение. Это помогает не забыть убрать комментарий после исправления кода.

Но как применить это к блоку? Ответ — никак напрямую. @ts-expect-error также работает только на одну строку. Однако, мы можем использовать трюк с немедленно вызываемой функцией (IIFE).

// Блок, который нужно игнорировать, обёрнут в IIFE
(function() {
    // @ts-expect-error — ожидаем ошибку в следующей строке
    const x: number = 'hello'; // Ошибка: Type 'string' is not assignable to type 'number'

    // @ts-expect-error — ещё одна ожидаемая ошибка
    console.log(x.length); // Ошибка: Property 'length' does not exist on type 'number'
})();

// Если убрать // @ts-expect-error, а ошибка осталась — TypeScript скажет спасибо

Плюсы:

  • Безопаснее, чем @ts-ignore — вы явно указываете, что ошибка ожидаема.
  • Помогает не забыть убрать игнорирование после рефакторинга.

Минусы:

  • Всё равно нужно ставить перед каждой строкой.
  • IIFE добавляет лишнюю обёртку, что может снизить читаемость.

Когда использовать: Если вы точно знаете, что ошибки временные (например, при миграции типов) и планируете их исправить в ближайшее время.

Подход 3: Кастомный утилитарный тип — изящное решение для блока

Самый интересный и гибкий подход — создать свой тип-обёртку, который «проглатывает» любые ошибки внутри блока. Это нестандартное решение, но оно работает как часы. Идея проста: мы используем any или as any для временного отключения типизации.

// Утилита: временно отключает типизацию для переданной функции
function ignoreTypes<T>(fn: () => T): T {
    return fn() as any;
}

// Использование: весь блок внутри игнорируется
const result = ignoreTypes(() => {
    const a: number = 'строка'; // Ошибка не будет показана
    const b = a + 10; // Любая операция — без проверки типов
    return { a, b };
});

console.log(result); // { a: 'строка', b: 'строка10' }

Этот подход можно расширить. Например, создать декоратор для методов класса или обёртку для асинхронных операций.

// Асинхронная версия
async function ignoreTypesAsync<T>(fn: () => Promise<T>): Promise<T> {
    return (await fn()) as any;
}

// Пример с async/await
const data = await ignoreTypesAsync(async () => {
    const response = await fetch('/api/dynamic');
    const json = await response.json();
    // Здесь могут быть любые ошибки типов — они игнорируются
    return json.user.profile.settings;
});

Плюсы:

  • Работает для целого блока любой длины.
  • Не требует изменения файла или глобальных настроек.
  • Легко найти по названию функции (удобно для code review).

Минусы:

  • Скрывает все ошибки внутри блока, включая опе

Блоги

Рекомендаций по книгам