[解決済み] TypeScript 2: 型付けされていない npm モジュールのためのカスタム型付け
質問
で投稿された提案を試した後 他の場所 に投稿された提案を試した後、私はタイプされていないNPMモジュールを使用するtypescriptプロジェクトを実行することができないことに気がつきました。以下は、最小限の例と私が試した手順です。
この最小限の例では、次のように仮定します。
lodash
は既存の型定義を持っていないことにします。そのため、パッケージ
@types/lodash
を無視し,その型付けファイルを手動で
lodash.d.ts
をプロジェクトに追加してみます。
フォルダの構造
-
ノードモジュール
- ロダッシュ
-
src
- foo.ts
-
型付け
-
カスタム
- lodash.d.ts
- グローバル
- index.d.ts
-
カスタム
- パッケージ.json
- tsconfig.json
- タイピング.json
次に、ファイルです。
ファイル
foo.ts
///<reference path="../typings/custom/lodash.d.ts" />
import * as lodash from 'lodash';
console.log('Weeee');
ファイル
lodash.d.ts
はそのままコピーされ、元の
@types/lodash
パッケージから直接コピーされます。
ファイル
index.d.ts
/// <reference path="custom/lodash.d.ts" />
/// <reference path="globals/lodash/index.d.ts" />
ファイル
package.json
{
"name": "ts",
"version": "1.0.0",
"description": "",
"main": "index.js",
"typings": "./typings/index.d.ts",
"dependencies": {
"lodash": "^4.16.4"
},
"author": "",
"license": "ISC"
}
ファイル
tsconfig.json
{
"compilerOptions": {
"target": "ES6",
"jsx": "react",
"module": "commonjs",
"sourceMap": true,
"noImplicitAny": true,
"experimentalDecorators": true,
"typeRoots" : ["./typings"],
"types": ["lodash"]
},
"include": [
"typings/**/*",
"src/**/*"
],
"exclude": [
"node_modules",
"**/*.spec.ts"
]
}
ファイル
typings.json
{
"name": "TestName",
"version": false,
"globalDependencies": {
"lodash": "file:typings/custom/lodash.d.ts"
}
}
ご覧のように、型付けをインポートする方法をいろいろと試してみました。
-
で直接インポートすることで
foo.ts
-
によって
typings
のプロパティでpackage.json
-
を使用することで
typeRoots
でtsconfig.json
というファイルに対してtypings/index.d.ts
-
明示的な
types
でtsconfig.json
-
を含めることで
types
ディレクトリをtsconfig.json
-
をカスタムで作成することで
typings.json
ファイルを作成しtypings install
なのに、Typescriptを実行すると
E:\temp\ts>tsc
error TS2688: Cannot find type definition file for 'lodash'.
私は何を間違えているのでしょうか?
どうすればいいのでしょうか?
残念ながらこれらのことは現在あまり文書化されていませんが、仮に動作させることができたとしても、各パーツが何をしているのか、そしてそれがどのように typescript が typing を処理しロードするかにどう関係しているのかを理解するために、設定を確認してみましょう。
まず、あなたが受け取ったエラーについて説明します。
error TS2688: Cannot find type definition file for 'lodash'.
このエラーは、実はインポートや参照、あるいはtsファイルのどこかでlodashを使おうとしていることが原因ではありません。むしろ、これは
typeRoots
と
types
プロパティがあるので、それらについてもう少し詳しく見ていきましょう。
についてですが
typeRoots:[]
と
types:[]
のプロパティは、それらが
ではない
任意の宣言を読み込むための汎用的な方法 (
*.d.ts
) ファイルを読み込む汎用的な方法です。
この2つのプロパティは、TS 2.0の新機能に直接関連しており、型付け宣言を NPM パッケージ .
これは非常に重要なことで、これらは NPM フォーマットのフォルダ (すなわち、"em" を含むフォルダ) に対してのみ動作することを理解してください。 package.json または index.d.ts ).
のデフォルトは
typeRoots
です。
{
"typeRoots" : ["node_modules/@types"]
}
デフォルトでは、これはtypescriptが
node_modules/@types
フォルダに入り、そこで見つけたすべてのサブフォルダを
npm パッケージ
.
フォルダがnpmパッケージのような構造を持っていない場合、これは失敗することを理解することが重要です。
これが、あなたのケースで起こっていることであり、最初のエラーの原因です。
typeRootをbeに切り替えています。
{
"typeRoots" : ["./typings"]
}
これは、typescript が
./typings
フォルダをスキャンして
サブフォルダ
で、見つかった各サブフォルダをnpmモジュールとして読み込もうとします。
では、先ほど
typeRoots
を指すように設定したとします。
./typings
を指すように設定されていますが、まだ
types:[]
プロパティがセットアップされていません。このようなエラーが表示される可能性があります。
error TS2688: Cannot find type definition file for 'custom'.
error TS2688: Cannot find type definition file for 'global'.
これは
tsc
をスキャンしているからです。
./typings
フォルダをスキャンし、サブフォルダ
custom
と
global
. そして、これらをnpmパッケージタイプのタイピングとして解釈しようとしている。
index.d.ts
または
package.json
というフォルダがあるため、このようなエラーが発生します。
さて、ここで少し
types: ['lodash']
プロパティについて少し説明します。これは何をするものなのでしょうか?デフォルトでは、typescript は
をすべて
サブフォルダを読み込みます。
typeRoots
. を指定すると
types:
プロパティを指定すると、それらの特定のサブフォルダのみが読み込まれます。
この例では
./typings/lodash
フォルダを読み込むように指示していますが、それは存在しません。このため、次のようになります。
error TS2688: Cannot find type definition file for 'lodash'
では、学んだことをまとめてみましょう。Typescript 2.0 が導入された
typeRoots
と
types
にパッケージされた宣言ファイルを読み込むために
npm パッケージ
. もし、カスタム型付けや単一の緩い
d.ts
ファイルがあり、それが npm パッケージの規約に従ったフォルダに含まれていない場合、これら 2 つの新しいプロパティは使うべきものではありません。Typescript 2.0 は、これらのファイルがどのように消費されるかを実際に変更することはありません。ただ、これらのファイルを、多くの標準的な方法でコンパイルコンテキストにインクルードする必要があります。
-
で直接インクルードする。
.ts
ファイルに記述します。///<reference path="../typings/custom/lodash.d.ts" />
-
含む
./typings/custom/lodash.d.ts
の中にfiles: []
プロパティに追加します。 -
含む
./typings/index.d.ts
の中にfiles: []
プロパティに追加します (これにより、他の型付けも再帰的に含まれます)。 -
追加する
./typings/**
にincludes:
うまくいけば、この議論に基づいて、あなたの
tsconfig.json
を変更したことで、再び動作するようになった理由を説明できるようになるとよいのですが。
EDITです。
ひとつ言い忘れていたのは
typeRoots
と
types
プロパティは、実際には
自動
ロードのためにのみ有用です。
例えば、もしあなたが
npm install @types/jquery
また、デフォルトのtsconfigを使用している場合、そのjquery typesパッケージは自動的にロードされ
$
はすべてのスクリプトで利用可能であり、それ以上
///<reference/>
または
import
は
typeRoots:[]
プロパティは、追加の場所を追加するためのもので、そこからタイプ
パッケージ
が自動的に読み込まれる場所を追加するものです。
この
types:[]
プロパティの主な用途は、(空の配列に設定することで)自動ロードの動作を無効にし、グローバルに含めたい特定のタイプのみをリストアップすることです。
型パッケージをロードする他の方法として、様々な
typeRoots
は、新しい
///<reference types="jquery" />
ディレクティブを使うことです。注目すべきは
types
ではなく
path
. 繰り返しますが、これはグローバルな宣言ファイルに対してのみ有効であり、典型的なものは
import/export
.
さて、ここで、混乱を招くもののひとつが
typeRoots
. 覚えていますか、私が言ったのは
typeRoots
はモジュールのグローバルインクルードについてだと言ったことを思い出してください。しかし
@types/folder
は標準的なモジュール解決にも関わってきます (あなたの
typeRoots
の設定に関係なく)。
具体的には、モジュールを明示的にインポートすることで、常にすべての
includes
,
excludes
,
files
,
typeRoots
と
types
というオプションがあります。 だから、そうすると
import {MyType} from 'my-module';
上記のプロパティはすべて完全に無視されます。の間に関連するプロパティは
モジュール解決
は
baseUrl
,
paths
そして
moduleResolution
.
基本的に
node
モジュール解決では、ファイル名の検索を開始します。
my-module.ts
,
my-module.tsx
,
my-module.d.ts
で指定されたフォルダを起点に
baseUrl
の設定によって指定されたフォルダを開始します。
もしファイルが見つからなければ、次のような名前のフォルダを探します。
my-module
という名前のフォルダを探し、さらに
package.json
を持つ
typings
プロパティがある場合、もし
package.json
がない場合、または
typings
プロパティがない場合、どのファイルを読み込むかを指定すると、そのファイルは
index.ts/tsx/d.ts
を探します。
それでもうまくいかない場合は、同じものを
node_modules
フォルダを探します。
baseUrl/node_modules
.
さらに、これらが見つからなければ、次のように検索します。
baseUrl/node_modules/@types
を検索します。
それでも見つからない場合は、親ディレクトリに移動して検索します。
node_modules
と
node_modules/@types
といった具合です。ファイルシステムのルートに到達するまで、ディレクトリを上り続けます(プロジェクト外のノードモジュールも取得します)。
ひとつ強調しておきたいのは、モジュールの解決はどんな
typeRoots
が設定されていても、完全に無視されるということです。ですから、もしあなたが
typeRoots: ["./my-types"]
を設定した場合、これは明示的なモジュール解決中に検索されることはありません。これは、インポートや参照を必要とせずにアプリケーション全体が利用できるようにしたいグローバル定義ファイルを置くためのフォルダとしてのみ機能します。
最後に、パスマッピングでモジュールの動作をオーバーライドすることができます (すなわち
paths
プロパティ) を使ってモジュールの動作を上書きすることができます。ですから、たとえば、任意のカスタム
typeRoots
は参照されないと書きました。しかし、もしあなたが好きなら、この動作を次のように実現することができます。
"paths" :{
"*": ["my-custom-types/*", "*"]
}
これは何をするかというと、左辺にマッチするすべてのインポートに対して、右辺のようにインポートを変更してから、それをインクルードしようとします(その際に
*
は最初のインポート文字列を表しています。たとえば、あなたがインポートした場合。
import {MyType} from 'my-types';
と書いたかのように、まずインポートを試します。
import {MyType} from 'my-custom-types/my-types'
そして、もし見つからなかったら、接頭辞なしで再試行します(配列の2番目の項目は単に
*
で、これは最初のインポートを意味します。
このように、カスタム宣言ファイルを検索するためのフォルダを追加したり、あるいはカスタム
.ts
モジュールを検索することができます。
import
.
また、特定のモジュールのためのカスタムマッピングを作成することもできます。
"paths" :{
"*": ["my-types", "some/custom/folder/location/my-awesome-types-file"]
}
これによって
import {MyType} from 'my-types';
しかし、次にこれらの型を
some/custom/folder/location/my-awesome-types-file.d.ts
関連
-
[解決済み] npm installの-saveオプションは何ですか?
-
[解決済み] tsc が `TS2307: Cannot find module` for a local file をスローします。
-
[解決済み] TypeScriptでObject.keysがkeyof型を返さないのはなぜですか?
-
[解決済み] タイプスクリプトのパイプ(|)の意味とは?
-
[解決済み] タイプスクリプト。カスタムタイプに対する typeof のチェック
-
[解決済み] TypeScript Genericsに複数の型制約を指定することは可能か?
-
[解決済み] spec/testフォルダを使用したtsconfigのセットアップ
-
[解決済み] TypeScriptで単一のプロパティをオプションにする
-
[解決済み] typescriptで非推奨のマークを付けることは可能ですか?
-
[解決済み] クラス内列挙型(TypeScript定義ファイル)
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み] TypeScriptのカスタムグローバルインターフェース(.d.tsファイル)を設定する方法は?
-
[解決済み] Typescriptでインターフェースやクラスを使用する場合 [重複].
-
[解決済み] Angular 2でアプリ起動時にサービスを実行する方法
-
[解決済み] Visual Studio Code - インポート引用符の設定を調整する
-
[解決済み] Promiseの型はどのようにアンラップするのですか?
-
[解決済み] TypeScriptをminifiedコードにコンパイルすることは可能ですか?
-
[解決済み] Typescript で Enum を制限付きキータイプとして使用する
-
[解決済み] エラー Typescript Feature 1.5。現在の言語レベルは1.4です。
-
[解決済み] TypeScriptで単一のプロパティをオプションにする
-
[解決済み] Angular2 canActivate() 非同期関数呼び出し