Ошибка «Имя модуля разрешается в нетипизированный модуль в…» при записи пользовательского файла определения TypeScript.


89

Я не могу найти определение TypeScript @type/{name}для одного из моих установленных пакетов NodeJS, поэтому я пытаюсь написать d.tsдля него файл и поместить файл в {project root}\typingsпапку. Вот как я делаю:

// My source code: index.ts
import Helper from 'node-helper-lib';


// My definition: \typings\node-helper-lib.d.ts
declare....(something else)

declare module 'node-helper-lib' {
   class Helper { ... }
   export = Helper;
}

Однако код Visual Studio продолжает выдавать эту ошибку и помещает красную линию под declare module 'node-helper-lib':

[ts] Недействительное имя модуля в дополнении. Модуль 'node-helper-lib' преобразуется в нетипизированный модуль в '{project path} \ node_modules \ node-helper-lib \ index.js', который не может быть расширен.

Разве это не законно, поскольку библиотека нетипизирована, поэтому мне должно быть разрешено добавлять в нее набор текста?

ОБНОВИТЬ:

Я использую:

  • TypeScript: 2.1.4
  • Код Visual Studio: 1.9.1
  • Узел JS: 6.9.4
  • Windows 10 x64

Ответы:


151

Фактическое решение приведено в комментарии @Paleo в ответе @hirikarate:

Импорт должен быть объявлен внутри объявления модуля.

Пример:

declare module 'node-helper-lib' {
   import * as SomeThirdParty from 'node-helper-lib';
   interface Helper {
       new(opt: SomeThirdParty.Options): SomeThirdParty.Type
   }
   export = Helper;
}

21
Это где-то задокументировано?
Крис

12
Не знаю, сколько часов мне понадобилось, чтобы наконец найти это. Большое спасибо! Это определенно должно быть лучше задокументировано ...
Джонатан Грубер

Почему у TypeScript нет хорошего сообщения об ошибке или чего-то подобного?
VitorLuizC

53

После нескольких попыток и ошибок я обнаружил, что это augmentationозначает «объявление модуля в одном файле с другими объявлениями модулей».

Поэтому, если мы хотим написать файл определения для нетипизированной сторонней библиотеки JavaScript, у нас должен быть ТОЛЬКО ОДИН declare module 'lib-name'в этом файле, и «имя-библиотеки» должно точно соответствовать имени библиотеки (можно найти в ее package.json, " имя "свойство").

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

Например:

// These module declarations are in same file, given that each of them already has their own definition file.
declare module 'events' {
   // Extended functionality
}

declare module 'querystring' {
   // Extended functionality        
}

declare module '...' { ... }

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


1
Что мне делать, если в стороннюю библиотеку уже включен файл определения .d.ts, но я хотел бы проигнорировать его и использовать собственный?
Ален Лян

24
Я пытаюсь написать файл определения для полностью нетипизированного модуля npm. supertestЖалоба TypeScript даже не имеет смысла, как я могу не дополнить то, что даже не имеет объявления? Я думал, что много раз писал подобные файлы определений ... [ts] Invalid module name in augmentation. Module 'supertest' resolves to an untyped module at '/home/chase/Desktop/projects/formuoli/node_modules/supertest/index.js', which cannot be augmented.- к сожалению, @types/supertestэто не работает из-за включения библиотек DOM, что делает его сломанным ... похоже, мне не повезло
ChaseMoskal

34
@ChaseMoskal: Возможно, в вашем файле .d.tsвам просто нужно переместить весь импорт в модуль объявления "moduleName" {}.
Paleo

17
@Paleo, это было именно то, что все importвызовы должны входить в declare module 'module' {}область видимости. ошибка в лучшем случае вводит в заблуждение
pocesar

2
typescript делает то же самое, если вы помещаете importинструкции, требуемые вашему модулю, вне, declare moduleа не внутри него. Такое не интуитивное странное поведение (извините за разглагольствование).
binki

0

Я тоже получал это сообщение об ошибке. Для меня проблема заключалась в том, что я пытался объявить другой модуль в существующем файле определения типа, в котором было объявление модуля. После того как я переместил объявление нового модуля в новый файл, ошибка исчезла.


-4

В моем случае я просто использовал следующее объявление в одном из моих файлов типов, поэтому я мог использовать все пакеты без машинописного текста:

declare module '*'
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.