Avatar ·

Ошибка "Could not find a declaration file for module" в TypeScript: решение

Привет! Я новичок в TypeScript и пытаюсь подключить библиотеку `lodash` в свой проект. Установил её через npm, но при импорте получаю ошибку: ``` Could not find a declaration file for module 'lodash'. '/node_modules/lodash/lodash.js' implicitly has an 'any' type. ``` Вот мой код: ```typescript import _ from 'lodash'; const arr = [1, 2, 3]; const shuffled = _.shuffle(arr); console.log(shuffled); ``` Проект создан через `tsc --init`, конфигурация tsconfig.json стандартная. Я проверил — библиотека `lodash` точно установлена в `node_modules`, но TypeScript ругается. Пробовал добавить `"noImplicitAny": false` в tsconfig, но это не помогло — ошибка осталась. Подскажите, пожалуйста, как правильно исправить эту проблему? Я слышал про файлы деклараций (.d.ts), но не понимаю, как они работают и где их брать. Может, нужно что-то дополнительно устанавливать? Буду благодарен за подробное объяснение для новичка. <<>>

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

TypeScript — это строго типизированный язык. Когда вы импортируете JavaScript-модуль (например, lodash), компилятору нужна информация о типах его функций, классов и переменных. Эта информация хранится в файлах деклараций с расширением .d.ts. Если такого файла нет, TypeScript считает модуль имеющим тип any и выдает ошибку (при включенном strict или noImplicitAny).

Решение: установка пакета с типами

Для большинства популярных библиотек существуют отдельные пакеты с декларациями. Они находятся в репозитории @types на npm и устанавливаются как dev-зависимости.

Для lodash выполните команду:

npm install --save-dev @types/lodash

После установки TypeScript автоматически найдет файл декларации в node_modules/@types/lodash. Ошибка исчезнет, и вы получите автодополнение и проверку типов:

import _ from 'lodash';

const arr: number[] = [1, 2, 3];
const shuffled: number[] = _.shuffle(arr); // теперь TypeScript знает тип результата
console.log(shuffled);

Что делать, если пакета @types нет?

Некоторые библиотеки не имеют отдельного пакета с типами. В таком случае есть три варианта:

  • Создать свой файл декларации — в корне проекта создайте файл declarations.d.ts и напишите:
    declare module 'имя-модуля';
    Это объявит модуль с типом any (временное решение).
  • Написать полноценную декларацию — если вы хотите точную типизацию, изучите API библиотеки и опишите её вручную. Например:
    declare module 'my-custom-lib' {
      export function doSomething(input: string): number;
    }
  • Отключить проверку для конкретного модуля — в tsconfig.json добавьте:
    {
      "compilerOptions": {
        "noImplicitAny": false
      }
    }
    Но это глобально отключит проверку типов для всех значений any, что не рекомендуется.

Проверка наличия типов

Перед установкой можно проверить, есть ли типы для библиотеки на сайте TypeScript DT Search. Или выполнить команду:

npm info @types/имя-библиотеки

Важные моменты

  • Устанавливайте @types/* как dev-зависимости (--save-dev), так как они нужны только во время разработки.
  • Некоторые библиотеки (например, express, react) уже содержат встроенные типы — в их package.json есть поле "types". В этом случае дополнительная установка не требуется.
  • Если вы используете yarn, команда будет: yarn add --dev @types/lodash.

Пример полного решения

// 1. Установка
npm install lodash
npm install --save-dev @types/lodash

// 2. Использование
import _ from 'lodash';

const result: number[] = _.shuffle([1, 2, 3]);
console.log(result); // OK
<<>>

Альтернативный подход: использование skipLibCheck

Если вы работаете с большим проектом, где много библиотек без типов, и не хотите устанавливать каждый пакет @types отдельно, можно использовать опцию skipLibCheck в tsconfig.json. Она отключает проверку типов для всех файлов деклараций (включая сторонние):

{
  "compilerOptions": {
    "skipLibCheck": true
  }
}

Это ускорит компиляцию, но вы потеряете автодополнение и проверку типов для всех библиотек. Подходит для прототипов или когда типы не критичны.

Дополнительный совет: использование allowJs

Если вы импортируете собственный JavaScript-модуль (не из npm), и он не имеет деклараций, включите опцию allowJs в tsconfig.json:

{
  "compilerOptions": {
    "allowJs": true,
    "checkJs": false // отключает проверку типов для JS-файлов
  }
}

Это позволит импортировать .js файлы без ошибок, но без типизации.

Когда это полезно

  • Вы используете устаревшую библиотеку, для которой нет @types.
  • Вы мигрируете проект с JavaScript на TypeScript и временно хотите избежать ошибок.
  • Производительность важнее строгой типизации (например, в больших монорепозиториях).