モジュール 'module-name'の宣言ファイルが見つかりませんでした。'/path/to/module-name.js'には暗黙的に 'any'タイプがあります


303

TypeScript モジュール解決の仕組みを読みました。

次のリポジトリがあります:@ ts-stack / 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

私のpackage.jsonで書いた"main": "dist/index.js"

Node.jsではすべてが正常に機能しますが、TypeScriptでは次のようになります。

import {Injector} from '@ts-stack/di';

モジュール '@ ts-stack / di'の宣言ファイルが見つかりませんでした。'/path/to/node_modules/@ts-stack/di/dist/index.js'は暗黙的に 'any'タイプを持ちます。

それでも、次のようにインポートすると、すべてが機能します。

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

何が悪いのですか?

回答:


295

他に2つのソリューションがあります

モジュールがあなたのものではない場合-からタイプをインストールしてみてください@types

npm install -D @types/module-name

上記のインストールエラーの場合- importステートメントをrequire次のように変更してみてください。

// import * as yourModuleName from 'module-name';
const yourModuleName = require('module-name');

13
あなたが名前を見つけることができませんでした取得する場合は活字体2.0のためにこれを実行する必要:npm install @types/node --save-dev
Ogglas

120
モジュールに@typesパッケージがない場合はどうなりますか?
Daniel Kmak

37
require代わりにを使用することimportは少しアンチパターンだと思います:モジュールを.d.tsファイルで宣言する方が良いです。以下の私の答えを参照してください。
レッサム

2
使用例: const mdbreact = require('mdbreact'); const { Button, Card, CardBody, CardText, CardTitle, CardImage } = mdbreact;
Sgedda '20

1
これは悪いアドバイスです。これは、TypeScriptのポイントと「十分に簡単なものは貢献する価値がある」という一般的なFOSSの姿勢を完全に否定します。タイピングaが欠落している場合、誰かの検索がそれを行っており、あなたのタイピングを使ってPRを発行または送信していないか、それを回避したいだけの場合はタイピングシステムを使用しないでください。
Dave Mackintosh

266

'foo'ライブラリ自体または@types/fooパッケージ(DefinitelyTypedリポジトリから生成されたもの)のいずれにも型付けを提供しないサードパーティのモジュールをインポートする場合は、モジュールを拡張子付きのファイル.d.ts。TypeScriptは、.d.ts通常の.tsファイルを検索するのと同じ場所でファイルを検索しますtsconfig.json

// 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がコンパイルされることです。


27
コンパイラはどこでd.tsファイルを探しますか?次のような設定を提供する必要がありますtypeRootsか?
トム

17
@Tom .d.ts通常の.tsファイルを検索するのと同じ場所でファイルを検索します:で「files」、「include」、および「exclude」を指定しtsconfig.jsonます。typeRootsこの目的での使用はお勧めしnode_modules/@typesません.d.ts。これは、個々のファイルではなく、外部型モジュール(つまり)の場所を対象としています。
Retsam

3
「ファイルfoo.d.tsはモジュールではありません」
Nathan H

2
このワイルドカードファイルは「typings.d.ts」と呼ばれる必要があるようです
jacob

4
この.d.tsファイルはどこに置くべきですか?
tonix

127

簡単な修正が必要な場合は、インポートの行の前にこれを追加するだけです。

// @ts-ignore

7
ありがとう、私の場合に最も役立つ答え。
David

これはeslintのそれ以降のバージョンでエラーが発生しますerror Do not use "// @ts-ignore" comments because they suppress compilation errors @typescript-eslint/ban-ts-ignore
Hykilpikonna

91

あなたが2日間外を見ていて、次のようにそれを見つけたときのその感覚:ちょうど中.jsから外し"main": "dist/index.js"package.json、すべてがうまくいく!

"main": "dist/index",

UPD:独自のnpmパッケージがある場合、この回答は相対的です。そうでない場合、以下の私の回答を参照しください。

そして、上記の答えが解決されない場合は、モジュールをインポートし、単に追加typingsしてみてくださいpackage.json

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

もちろん、ここにフォルダがありますdist-モジュールのファイルを格納する場所です。


私はあなたの質問と答えにこれらの最後の日に何度も来ました、そして私が欠けていたのはそれらのタイプを.d.tsファイルで宣言することでしたので、私の場合、インストールされていないノードモジュールをインストールしましたタイプ(および私は明示的にそれらのタイプをインストールできませんでした)は、 "declare module 'MYDesiredModule'
Juan

ありがとう。"typings": "dist / index"を私のpackage.jsonに追加すると、うまくいきました。TypeScriptを使用していないときにVS Codeがtypescriptエラーをスローするのは奇妙です
2018

あなたの洞察をありがとう!定義に移動しようとすると、VS Code定義が自分のnpmパッケージで機能しない理由を教えてください。私はここに質問を作成し、これまでに...運がなかったしているstackoverflow.com/questions/59128917/...
tonix

あなたはdistフォルダに "index.d.ts"ファイルを追加declare module "moduleName" し、その間に置く必要があります
Sunny Sun

42

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ルールを守ることができます。


私がタイピングファイルに名前を付けた場合にのみ機能しましたindex.d.ts。それ以外は、これが私にとって万能な唯一の解決策でした。
クリスヘインズ

21

これを読んでいる人は誰でも、.jsファイルの名前を.tsに変更してみてください。

編集:"allowJs": truetsconfigファイルに追加することもできます。


ええ、「react-fusioncharts」と同じ問題があり、このソリューションは魅力のように機能しました。
あくびファントム

16

この方法は私にとってはうまくいきます:

1. index.d.tsなどの宣言ファイルに独自の宣言を追加します(おそらくプロジェクトルートの下にあります)
declare module 'Injector';
2. index.d.tsを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
    }

-編集:モジュール名の前後に必要な引用符


4

typescriptで記述された反応アプリケーションでノードモジュールを使用すると、同じ問題が発生しました。モジュールはを使用して正常にインストールされましたnpm i --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。つまりfalsetsconfig.jsonファイルの次の行に設定しました。

    "noImplicitAny": false,

14
つまり、これは機能しますが、残りのコードを厳密に入力する機能が失われます。それは素晴らしい回避策ではありません。
phillyslick

3

あなたを修正するのは簡単です:

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

オブジェクトのインターフェースを宣言したい場合(大きなプロジェクトに推奨)使用できます:

// example.d.ts
declare module 'foo'{
    // example
    export function getName(): string
}

どうやって使うの?シンプルな

const x = require('foo') // or import x from 'foo'
x.getName() // intellisense can read this

2

私もこれを取得しており、モジュールとタイプがすでにインストールされていて、IDEを何度かリロードしても、しばらく困惑していました。

私の場合それを修正したのは、ターミナルプロセスを終了し、を削除node_modulesし、ノードのパッケージマネージャーキャッシュをクリアして、新たに実行してinstallからエディターを再ロードすることでした。


2

残念ながら、パッケージ作成者が宣言ファイルに悩まされるかどうかは私たちの手に負えません。私がしがちなのはindex.d.ts、さまざまなパッケージから欠落している宣言ファイルがすべて含まれるファイルを用意することです。

Index.ts:

declare module 'v-tooltip';
declare module 'parse5';
declare module 'emoji-mart-vue-fast';


0

私はここですべてを試しましたが、私にとってはまったく別の問題でした:*.d.tsインポートステートメントから削除する必要がありました:

import { SomeModuleType } from '3rd-party-module';

エラーを取り除いた後、消えました...

明確化*.d.tsファイルでモジュールを宣言すると、Typescriptコンパイラによってアンビエントモジュール(明示的にインポートする必要のないモジュール)として自動的に取得されます。を指定するimport ... from ...と、ファイルは通常の(ES6)モジュールになるため、自動的に取得されません。したがって、それをアンビエントモジュールとして動作させたい場合は、次のように別のインポートスタイルを使用します。

type MyType: import('3rd-party-module').SomeModuleType;

-4

単に次のコードのようにrequireを使用してインポートできます。

var _ = require('your_module_name');
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.