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
私のpackage.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';
何がおかしいのですか?
あなたが2日間外を見ていて、それがこのようにそれを見つけるとき、その気持ち:ちょうど.js
の"main": "dist/index.js"
からpackage.json
を取り除けば、すべてうまくいきます!
"main": "dist/index",
_ upd _ :あなたがあなた自身のnpmパッケージを持っているなら、この答えは相対的です。そうでなければ - 以下の私の答えを見てください 。
そして上記の答えがあなたのモジュールをインポートすることで解決されないならば、単にpackage.json
にtypings
を加えてみてください:
"main": "dist/index",
"typings": "dist/index",
もちろん、ここでフォルダdist
- それはあなたのモジュールのファイルを保存する場所です。
他に2つの解決策があります
モジュールがあなたのものではない場合 - @types
から型をインストールするようにしてください。
npm install -D @types/module-name
上記のインストールエラーが発生した場合 - import
ステートメントをrequire
に変更してみてください。
// import * as yourModuleName from 'module-name';
const yourModuleName = require('module-name');
ライブラリ自体または'foo'
パッケージ( DefinitelyTyped repositoryから生成)のいずれかでタイピングを提供しないサードパーティ製モジュール@types/foo
をインポートする場合は、このエラーを回避することができます。 .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がコンパイルするということです。
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
ファイルに移動し、compilerOptions
に(フォルダーへの適切な相対パスを指定して)"typeRoots": [ "../../typings", "../../node_modules/@types"]
を追加して、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の規則に従うことができます。
迅速な修正が必要な場合は、単にインポートの前にこれを追加してください。
// @ts-ignore
この方法は私のために働く:
declare module Injector;
{
"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
}
私は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
を気にしない、つまりtsconfig.json
ファイルの次の行をfalse
に設定するようにコンパイラーに指示して、問題を解決しました。
"noImplicitAny": false,
私もこれを手に入れていました、モジュールとタイプがすでにインストールされていて私のIDEを数回リロードしていてもしばらくの間困惑していました。
私の場合、それを修正したのは、端末プロセスを終了し、node_modules
を削除し、ノードパッケージマネージャのキャッシュをクリアし、新たにinstall
を実行してからエディタを再ロードすることでした。
npm install --save TypeScript @types/node @types/react @types/react-dom @types/jest
yarn add TypeScript @types/node @types/react @types/react-dom @types/jest