Avatar ·

Ошибка "requires an imported helper but module 'tslib' cannot be found" при использовании ES2015 модулей в TypeScript

Привет всем! Я новичок в TypeScript и пытаюсь настроить проект. У меня есть простой файл index.ts с таким кодом: ```typescript class User { constructor(public name: string, public age: number) {} greet() { return `Привет, меня зовут ${this.name}`; } } const user = new User("Анна", 25); console.log(user.greet()); ``` В моём tsconfig.json я указал: ```json { "compilerOptions": { "target": "ES5", "module": "ES2015", "outDir": "./dist", "strict": true } } ``` Когда я запускаю компиляцию через `tsc`, я получаю ошибку: ``` error TS2802: This syntax requires an imported helper but module 'tslib' cannot be found. ``` Я гуглил эту ошибку, но не до конца понимаю, что значит "imported helper" и почему это связано с tslib. Я не устанавливал никаких дополнительных пакетов, только сам TypeScript. Можете объяснить, в чём проблема и как её исправить? Почему эта ошибка возникает именно при использовании ES2015 модулей, а с CommonJS всё работает нормально? Заранее спасибо за помощь! <<>>

Причина ошибки

Ошибка возникает из-за того, что TypeScript при компиляции в ES5 использует вспомогательные функции (helpers) для реализации некоторых возможностей ES6+. Например, для работы классов с наследованием или декораторов. При компиляции с module: "ES2015" TypeScript ожидает, что эти helpers будут импортированы из пакета tslib, а не встроены в каждый файл (как это делается при module: "CommonJS").

Когда вы используете CommonJS, TypeScript просто копирует код helpers в каждый скомпилированный файл. Это приводит к дублированию кода, но не требует внешних зависимостей. При ES2015 модулях TypeScript оптимизирует размер бандла, вынося helpers в отдельный модуль tslib, который должен быть установлен в проекте.

Решение 1: Установка tslib (рекомендуется)

Самый правильный способ — установить пакет tslib как зависимость:

npm install tslib --save

После этого компиляция должна пройти успешно. TypeScript автоматически найдёт tslib в node_modules и будет импортировать helpers оттуда.

Решение 2: Отключение импорта helpers

Если вы не хотите устанавливать дополнительную зависимость, можно отключить использование внешних helpers в tsconfig.json:

{
    "compilerOptions": {
        "target": "ES5",
        "module": "ES2015",
        "outDir": "./dist",
        "strict": true,
        "importHelpers": false  // Добавьте эту строку
    }
}

Однако это приведёт к тому, что helpers будут встроены в каждый скомпилированный файл, что увеличит размер бандла.

Решение 3: Изменение target

Если ваш проект не требует поддержки старых браузеров, можно изменить target на ES2015 или выше:

{
    "compilerOptions": {
        "target": "ES2015",  // Изменили с ES5 на ES2015
        "module": "ES2015",
        "outDir": "./dist",
        "strict": true
    }
}

В этом случае helpers не понадобятся, так как классы, стрелочные функции и другие конструкции ES6+ поддерживаются нативно.

Почему с CommonJS работает без tslib?

При использовании module: "CommonJS" TypeScript по умолчанию встраивает helpers в каждый файл. Это поведение контролируется опцией importHelpers, которая по умолчанию false для CommonJS и true для ES2015 модулей. Когда вы переключаетесь на ES2015, TypeScript автоматически включает importHelpers: true, что требует наличия tslib.

Лучшая практика — всегда устанавливать tslib как зависимость при использовании ES2015 модулей с компиляцией в ES5. Это уменьшает размер итогового бандла и следует принципу DRY (Don't Repeat Yourself).

<<>>

Альтернативный подход: использование importHelpers вручную

Если вы хотите контролировать, какие именно helpers импортируются, можно явно указать importHelpers: true в tsconfig.json и установить tslib. Это даёт дополнительную гибкость:

{
    "compilerOptions": {
        "target": "ES5",
        "module": "ES2015",
        "outDir": "./dist",
        "strict": true,
        "importHelpers": true,
        "downlevelIteration": true  // если используете итерации
    }
}

Обратите внимание, что importHelpers: true включён по умолчанию для ES2015 модулей, поэтому явно указывать его не обязательно. Однако это может помочь в отладке, если вы используете нестандартную конфигурацию.

Также стоит проверить, не конфликтует ли ваша версия TypeScript с версией tslib. Обычно последняя версия tslib совместима с TypeScript 2.1 и выше. Если ошибка остаётся после установки, попробуйте перезапустить редактор или очистить кэш TypeScript.

Ещё один совет: если вы используете сборщик (Webpack, Rollup), убедитесь, что он правильно обрабатывает внешние модули. В некоторых случаях может потребоваться настроить externals или плагины для работы с tslib.