次のように、外部TypeScriptモジュールのセットを作成しようとしています。
// ClassA.ts
export default class ClassA {
public method() { return true; }
}
// ModuleB.ts
import ClassA from './ClassA';
var moduleB = {
ClassA: ClassA
};
export default moduleB;
// ModuleA.ts
import moduleB from './ModuleB';
var moduleA = {
moduleB: moduleB
}
export default moduleA;
これはコンパイルされ、ライブラリとして提供されるという考え方です。 計画では、ライブラリのコンシューマーは次のようにClassAのインスタンスをインスタンス化します。
import moduleA from './ModuleA';
var anInstance = moduleA.moduleB.ClassA();
これは、予想されるJSにコンパイルされているように見えますが、エラーコンパイラエラーが発生し、詳細情報を見つけるのに苦労しています。
Using tsc v1.6.2
.../src/ModuleA.ts(3,5): error TS4023: Exported variable 'moduleA' has or is using name 'ClassA' from external module ".../src/ClassA" but cannot be named.
ここの誰かがこの問題に光を当てることができますか? 私がやろうとしていることは理にかなっていますか?
ああ-これがこの質問をするのに適した場所ではない場合。 お知らせください。別のメディアに投稿させていただきます。
FWIWは通常、Stack Overflowでより迅速な回答が得られますが、ここでは適切に表現された質問を行います。
ここでの問題は、 --declaration
フラグを使用しているが、コンパイラーがそのジョブを実行する方法を提供していないことです。
ModuleA.d.ts
を発行しようとすると、コンパイラはモジュールの形状を表すオブジェクト型リテラル( { moduleB: { classA: *mumble?* } }
)を記述する必要があります。 ただし、スコープ内にclassA
を直接参照する名前がないため、「名前を付けることができません」というタイプであり、エラーが発生します。
ClassA
import
のClassA
をModuleA.ts
に追加すると、エラーは解消されます。
こんにちはライアン-アドバイスREスタックオーバーフローとアドバイスに感謝します-インポートをModuleA
追加すると、期待どおりにコンパイルされました。
ここでのちょっとしたコンテキスト-ここでの私の目標は、実際に外部モジュールの宣言を生成することです。 (私が信じている何かがまだ完全に機能していないのですか?#5039?)このインポートは完全に必要かもしれませんが、moduleBがすでにエクスポートしているシンボルをインポートする必要があるのはModuleA
にとって少し奇妙に感じます。 その結果、 ModuleB
のオブジェクトエクスポートに追加するたびに、インポートをModuleA
直接追加する必要があります。
import {moduleB} from './moduleB';
import {ClassA} from './ClassA';
またはModuleB
経由(両方の場所でClassA
パスの指定を減らすため):
import {moduleB, ClassA} from './moduleB';
TSコンパイラについてはほとんど知らないので、私が言っていることは完全に非現実的かもしれませんが、最初はコンパイラがModuleB
がN個のシンボルを含むオブジェクトをエクスポートしていると推測できるように思われるのでModuleA
はこれらの記号が必要ですか? ModuleB
のインポート情報はすでにあります- ModuleA
はそれを使用できますか? インポートためか、それは不可能であろうClassA
に完全に内部にあるModuleB
ので、コンパイラがためにタイプを推測できるという方法はありません、 ClassA
の定義を作成するときにModuleA
?
お時間を割いていただき、誠にありがとうございます。 私は今私の問題を分類したので、上記は主に好奇心です-答えるのを急ぐ必要はありません。
あなたが何を言っているのか正確にはわかりません。 この提案では、 ModuleA.d.ts
どのように見えるべきですか?
コンパイラーは、宣言を発行するときに、ユーザーコードに存在しなかった依存関係(つまり、インポートステートメント)を追加しません。 発生するエラーは、コンパイラがエクスポートされた宣言の型注釈を書き込もうとしているが、書き込めなかったことを意味します。 これには、名前にアクセスできない、つまり現在のモジュールにインポートされていない、または元の宣言をシャドウイングしている宣言があるという2つの理由のいずれかが考えられます。
どちらの場合も、回避策は明示的な型注釈を追加することです。型注釈を追加すると、出力に逐語的に出力されます。 もう1つのオプションは、名前にアクセスできることを確認することです。つまり、モジュールへのインポートがあり、モジュールをインポートしているユーザーにとってそれが何を意味するかを理解しています。
@mhegazyは言った:
コンパイラーは、宣言を発行するときに、ユーザーコードに存在しなかった依存関係(つまり、インポートステートメント)を追加しません。
問題は、コードにimportステートメントが常に必要なわけではなく(明らかに、 --declarations
なくても機能するため)、それらを含めるとノイズが多く、 tslint
が「未使用のインポート」。 コンパイラが発行されたJavaScriptに依存関係を追加したくない理由はわかりますが、発行された宣言に依存関係を追加することの問題は何ですか?
この提案を追跡するには、問題をログに記録してください。 インポートは依存関係の宣言であり、コンパイラーは、指示がない限り、インポートを作成しないでください。
これは、より深刻な結果をもたらす可能性があります。
moduleA
-> moduleB
-> moduleC
-> moduleD
検討してください。
moduleB
は、この問題を回避するためにimport { ABC } from 'moduleA'
を実行する必要があるものです。
moduleC
がmoduleB
を使用してその署名をエクスポートすると、 moduleB
はABC
からmoduleA
ABC
を必要とするため、コンパイルに失敗しますが、今回はmoduleB
はそれをエクスポートしませんでした。
これは次のいずれかを意味します。
moduleC
のハード依存持っている必要がありますmoduleA
して、インポートABC
moduleB
は、インポートするだけでなく、 ABC
を再エクスポートしてから、 moduleC
インポートする必要があります。moduleD
が同様のことを行う場合、基本的には依存関係のチェーン全体を知る必要があります。
typings
を使用していて、ブロックする問題があるため、これをテストしてそれが事実であることを証明できませんでした: https :
編集:私はそれを再現することができます、そして確かに私のmoduleD
はインポートをするためにmoduleA
を参照する必要があります。
私の例では:
moduleA
=> redux
moduleB
=> redux-thunk
moduleC
=> redux-thunk
上にカスタムコードmoduleD
=>いくつかのライブラリABC
=> redux
Dispatch
インターフェース@unionalで説明されているのと同じ問題があり
この問題を再度開いてください。
発行https://github.com/Microsoft/TypeScript/issues/9944トラックは、宣言の発行フェーズでインポートを追加し
感謝!
インポートを追加する際の問題は、 noUnusedLocals
すると、コンパイラが使用されていない型について文句を言うことです。 明示的な型アノテーションを追加することはできますが、推論が得られません。 例:
class Whatever {
fetch(uri: string): Promise<void> { }
ensureFetched = MemoizedFunction<(uri: string) => Promise<void>> = memoize((uri: string) => this.fetch(uri))
}
ensureFetched
型注釈を省略したい
私はこれの回避策を見つけました:
tsconfigの場合: include: [ ..., "node_modules/@your_scope/your_library" ]
頑張って楽しんでください:smiley:
@ salim7これにより、コンパイル時間が遅くなり(すでにコンパイルされているはずのライブラリを再コンパイルしているため)、ターゲットライブラリで厳密性設定の最小公分母を使用する必要があります。
@mhegazy問題は次のシナリオで再現されました:
import * as Foo from "./Foo";
export class Bar {
baz = new Foo.Baz(); // Compiler forgot "Foo." prefix in the type, and throws this error, because "Baz" without perfix is not imported.
getBaz() { // All the same
return new Foo.Baz();
}
}
解決策は、明示的な型を指定することです。
import * as Foo from "./Foo";
export class Bar {
baz: Foo.Baz = new Foo.Baz(); // ok
getBaz(): Foo.Baz { // ok
return new Foo.Baz();
}
}
上記のサンプルを使用してこれを再現することはできません。 新しいバグを報告し、問題を再現できるように、より多くのコンテキストを提供してください。
@PFightありがとうございます! それは私にとってそれでした!
私は使用時にこの問題に直面しました:
export { IMyInterface } from './file'
````
The solution was to do this:
```ts
import { IMyInterface } from './file'
export { IMyInterface }
しかし、これは本当に必要なはずではありません。
noUnusedLocals
扱い方を誰かが理解しましたか?
@yordis // @ts-ignore
@pelotomええ、これは完全に私のせいです、
私はあることを考えていて、別のことを書きました。
TypescriptはnoUnusedLocals
と宣言の間の問題を修正しましたか?
私の現在の回避策は、私にとって完全な苦痛のように感じますが、
import {SomeInterface} from "./SomeFile";
const _dummySomeInterface : undefined|SomeInterface = undefined;
_dummySomeInterface;
//Code that implicitly uses SomeInterface
noUnusedLocals
回避し、可能な場合はジェネリックインターフェイスの型推論も可能にします。
最も参考になるコメント
FWIWは通常、Stack Overflowでより迅速な回答が得られますが、ここでは適切に表現された質問を行います。
ここでの問題は、
--declaration
フラグを使用しているが、コンパイラーがそのジョブを実行する方法を提供していないことです。ModuleA.d.ts
を発行しようとすると、コンパイラはモジュールの形状を表すオブジェクト型リテラル({ moduleB: { classA: *mumble?* } }
)を記述する必要があります。 ただし、スコープ内にclassA
を直接参照する名前がないため、「名前を付けることができません」というタイプであり、エラーが発生します。ClassA
import
のClassA
をModuleA.ts
に追加すると、エラーは解消されます。