Не удалось найти файл объявления для модуля 'module-name'. '/path/to/module-name.js' неявно имеет тип 'any'

92

Я читаю, как работает разрешение модуля TypeScript.

У меня есть следующий репозиторий: ts-di. После компиляции структура каталогов выглядит следующим образом:

├── dist
│   ├── annotations.d.ts
│   ├── annotations.js
│   ├── index.d.ts
│   ├── index.js
│   ├── injector.d.ts
│   ├── injector.js
│   ├── profiler.d.ts
│   ├── profiler.js
│   ├── providers.d.ts
│   ├── providers.js
│   ├── util.d.ts
│   └── util.js
├── LICENSE
├── package.json
├── README.md
├── src
│   ├── annotations.ts
│   ├── index.ts
│   ├── injector.ts
│   ├── profiler.ts
│   ├── providers.ts
│   └── util.ts
└── tsconfig.json

В моем пакете.json я написал "main": "dist/index.js".

В Node.js все работает отлично, но TypeScript:

import {Injector} from 'ts-di';

Не удалось найти файл декларации для модуля ts-di. '/path/to/node_modules/ts-di/dist/index.js' неявно имеет тип "any".

И все же, если я импортирую как следует, то все работает:

import {Injector} from '/path/to/node_modules/ts-di/dist/index.js';

Что я делаю неправильно?

Теги:
node-modules

9 ответов

59
Лучший ответ

Это чувство, когда вы смотрите на два дня и находите это так: просто удалите .js из "main": "dist/index.js" в package.json, и все будет хорошо!

"main": "dist/index",

UPD: этот ответ относительный, если у вас есть собственный пакет npm, если нет - см. мой ответ ниже.

И если выше ответ не разрешен импорт вашего модуля, попробуйте просто добавить typings в package.json:

"main": "dist/index",
"typings": "dist/index",

Конечно, вот папка dist - она ​​хранит ваши файлы модулей.

  • 0
    спасибо, что вернулись и разместили свои ответы :)
  • 0
    Я приходил к вашему вопросу и вашему ответу много раз в последние дни, и я хотел бы добавить, что мне не хватало, чтобы объявить эти типы в файле .d.ts, поэтому в моем случае были установлены модули узлов, которые поставлялись без типы (и я не смог установить explicity их типы) начали работать, объявив их в этом файле, написав «объявлять модуль« MYDesiredModule »
Показать ещё 1 комментарий
131

Еще два способа, когда модуль не принадлежит вам - просто попробуйте установить его из @types:

npm install -D @types/module-name

Или, если ошибка установки - попробуйте переписать import на require:

// import * as yourModuleName from 'module-name';
const yourModuleName = require('module-name');
  • 9
    Если вы не можете найти имя, запустите это для TypeScript 2.0: npm install @types/node --save-dev
  • 51
    Что делать, если модуль не имеет пакета @types?
Показать ещё 5 комментариев
56

Если вы импортируете сторонний модуль 'foo', который не предоставляет никаких типов, либо в самой библиотеке, либо в пакете @types/foo (сгенерированном из репозитория DefinitelyTyped), вы можете сделать эту ошибку прочь, объявив модуль в файле .d.ts:

// foo.d.ts
declare module 'foo';

Затем, когда вы импортируете foo это будет просто введено как any.


Кроме того, если вы хотите перевернуть свои собственные тиски, вы также можете это сделать:

// foo.d.ts
declare module 'foo' {
    export function getRandomNumber(): number
} 

Тогда это скомпилируется правильно:

import { getRandomNumber } from 'foo';
const x = getRandomNumber(); // x is inferred as number

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


С другой стороны, если вы не заботитесь о типизации внешних библиотек и хотите, чтобы все библиотеки без типизаций были импортированы как any, вы можете добавить это в файл .d.ts:

declare module '*';

Выгода (и минус) этого заключается в том, что вы можете импортировать абсолютно все, и TS будет компилироваться.

  • 6
    где компилятор ищет файлы d.ts ? Вы должны предоставить какую-либо конфигурацию, такую как typeRoots ?
  • 4
    @Tom Он ищет файлы .d.ts в тех же местах, что и обычные файлы .ts : как указано «files», «include» и «exclude» в tsconfig.json . Я бы не рекомендовал использовать typeRoots для этой цели: он предназначен для размещения модулей внешнего типа (то есть node_modules/@types ), а не отдельных файлов .d.ts .
Показать ещё 8 комментариев
11

TypeScript в основном реализует правила и добавляет типы в ваш код, чтобы сделать его более понятным и точным из-за отсутствия ограничений в Javascript. TypeScript требует, чтобы вы описали свои данные, чтобы компилятор мог проверить ваш код и найти ошибки. Компилятор сообщит вам, если вы используете несогласованные типы, если вы находитесь вне области действия или вы пытаетесь вернуть другой тип. Поэтому, когда вы используете внешние библиотеки и модули с помощью TypeScript, они должны содержать файлы, описывающие типы в этом коде. Эти файлы называются файлами декларации типа с расширением d.ts Большинство типов объявлений для модулей npm уже написаны, и вы можете включить их, используя npm install @types/module_name (где module_name - это имя модуля, типы которого вы хотите включить).

Тем не менее, существуют модули, которые не имеют определений типов, и чтобы ошибка исчезла и импортировала модуль с помощью import * as module_name from 'module-name', создайте папку, typings в корне вашего проекта, внутри создайте новую папку с именем вашего модуля и в этой папке создайте файл module_name.d.ts и напишите declare module 'module_name'. После этого просто зайдите в файл tsconfig.json и добавьте "typeRoots": [ "../../typings", "../../node_modules/@types"] в compilerOptions (с соответствующим относительным путем к ваши папки), чтобы позволить TypeScript знать, где он может найти определения типов ваших библиотек и модулей и добавить новое свойство "exclude": ["../../node_modules", "../../typings"] в файл. Вот пример того, как должен выглядеть ваш файл tsconfig.json:

{
    "compilerOptions": {
        "module": "commonjs",
        "noImplicitAny": true,
        "sourceMap": true,
        "outDir": "../dst/",
        "target": "ESNEXT",
        "typeRoots": [
            "../../typings",
            "../../node_modules/@types"
        ]
    },
    "lib": [
            "es2016"
    ],
    "exclude": [
        "../../node_modules",
        "../../typings"
    ]
}

Делая это, ошибка исчезнет, и вы сможете придерживаться последних правил ES6 и TypeScript.

0

Этот способ работает для меня:

1. добавьте свое собственное объявление в файл объявлений, такой как index.d.ts (возможно, в корне проекта)
declare module Injector;
2. добавьте ваш index.d.js в tsconfig.json
  {
    "compilerOptions": {
        "strictNullChecks": true,
        "moduleResolution": "node",
        "jsx": "react",
        "noUnusedParameters": true,
        "noUnusedLocals": true,
        "allowSyntheticDefaultImports":true,
        "target": "es5",
        "module": "ES2015",
        "declaration": true,
        "outDir": "./lib",
        "noImplicitAny": true,
        "importHelpers": true
      },
      "include": [
        "src/**/*",
        "index.d.ts",   // declaration file path
      ],
      "compileOnSave": false
    }
0

У меня была та же проблема с использованием модуля узла с приложением реагирования, написанным на машинописи. Модуль был успешно установлен с помощью npm я --save my-module. Он написан на javascript и экспортирует класс Client.

С:

import * as MyModule from 'my-module';
let client: MyModule.Client = new MyModule.Client();

Компиляция завершается с ошибкой:

Could not find a declaration file for module 'my-module'. 
'[...]/node_modules/my-module/lib/index.js' implicitly has an 'any' type.
  Try 'npm install @types/my-module' if it exists or add a new declaration (.d.ts) file containing 'declare module 'my-module';'

@types/my-module не существует, поэтому я добавил файл my-module.d.ts рядом с файлом, в который импортируется my-module, с предложенной строкой. Я тогда получил ошибку:

Namespace '"my-module"' has no exported member 'Client'.

Клиент фактически экспортируется и работает нормально, если я использую его в приложении js. Кроме того, предыдущее сообщение говорит мне, что компилятор ищет нужный файл (/node_modules/my-module/lib/index.js определен в my-module/package.json элемент "main").

Я решил проблему, указав компилятор я не заботиться о неявном any, то есть, я поставил в false следующую строку tsconfig.json файла:

    "noImplicitAny": false,
  • 1
    Я имею в виду, это работает, но вы теряете возможность строго набирать остальную часть вашего кода. Это не отличный обходной путь.
0

Я тоже это получал, на какое-то время я был сбит с толку, даже с уже установленным модулем и типами и перезагружал мою IDE несколько раз.

В моем случае это исправляло завершение процессов терминала, удаление node_modules, очистку кеша менеджера пакетов узлов и повторную install затем перезагрузку редактора.

0

Я решил эту проблему просто так:

import * as foo from "foo";

В моем случае эта проблема возникла, когда я пытался использовать класс по умолчанию, экспортируемый библиотекой.

-1

У меня была такая же проблема, и я решил ее, обновив tsconfig.json compilerOptions следующим образом:

{
  "compilerOptions": {
    ...
    "noImplicitAny": false,
    ...
  },
  "exclude": [
    ...
  ]
}

Ещё вопросы

Сообщество Overcoder
Наверх
Меню