2016-07-26 17 views
0

私はcommon.jsモジュールの規則を使用しています。これは、テスト用にnode.jsを、browserifyを使用して単一の.jsファイルを作成するためです。現在、私のモジュールは循環的に依存しています。私がしたいのは、モジュールvalueがモジュールpnodeに依存していることをコンパイル時に示すことです。私。実行時の依存関係にはエラーとしてフラグが立てられます。例えば。モジュールpnodeがタイプTを宣言している場合、モジュールvalueで、var a : pnode.Tのような宣言をエラーなしでコンパイルしたいが、new pnode.T()またはa instanceof pnode.Tのような式は実行時の依存関係を作成するためエラーになります。Typescript。コンパイル時と実行時の依存関係を区別できますか?

これを行う方法はありますか?

動機:現在pnodeおよびvalueは循環に依存しています。実行時に循環依存がない限り、大丈夫です。実行時の循環依存性は、node.jsが正しく処理しないか、警告することさえできないため、問題を引き起こします。私の現在のコードは、この

ファイルpnode.ts

import value = require('./value') ; 

module pnode { 

    export abstract class Label { 
    } 
    export class LambdaLabel { 
     step() { 
      return new value.ClosureV(this) ; 
     } 
    } 
} 

export = pnode ; 

私が試したどのようなファイルvalue.ts

import pnode = require('./pnode') ; // Would like to avoid this. 

module value { 

    export class ClosureV { 

     constructor(func : pnode.Label) { 

      if (func instanceof pnode.Label) // Would like an error here. 
       console.log("a") ; else console.log("b") ; 
     } 
    } 
} 

export = value; 

のように見えます。私は

/// <reference path="pnode.ts" /> 

でライン

import pnode = require('./pnode') ; // Would like to avoid this. 

を交換してトリックを行うかもしれないと期待していたが、それはしませんでした。私がコンパイル時の循環依存を排除​​することを考慮した様々な方法があるので、これは私のフォールバックオプションです。あなたはそれを参照するとき次に

declare module pnode { 
    abstract class Label { 
    } 
    class LambdaLabel { 
     step(): any; 
    } 
} 
export = pnode; 

/// <reference path="test.d.ts" /> 

module value { 
    export class ClosureV { 
     constructor(func : pnode.Label) {} 
    } 
} 

をあなたが説明したエラーを取得します:あなたが宣言フラグでpnode.tsをコンパイルする場合

+2

モジュールの '.d.ts'ファイルをコンパイラに出力させ、' value.ts'から 'pnode.d.ts'を参照することができます。そのようにすれば、コンパイラには「これらの定義は正常であり、実行時に存在します」と伝えられます。もう一つの選択肢は、これらのファイルからすべての共有タイプを第3のものに移動し、 'shared'と言うと、これらのモジュールの両方が' shared'を参照し、循環依存を避けることです。 –

+0

@NitzanTomerありがとうございました。これは有望ですね。私はpnode.d.tsを生成し、 'import pnode = require( './ pnode');'を削除し、代わりに '/// 'を追加しました。しかし、今は 'pnode.Label'が使われているところでエラーが出ます。エラーは '名前空間が見つかりません 'pnode'' –

答えて

0

あなたはこの.d.tsファイルを取得しますCannot find namespace 'pnode'を。
この.d.tsファイルは、export = pnode;で終わるので、CommonJSモジュールを表すことをコンパイラーが認識しているからです。

この行を削除する(またはコメントアウトする)と、エラーは消えます。コンパイルするたびにこの行を削除する必要がありますが(またはあなたのためのスクリプトを作成する必要があります)、それはうまくいきます。

いずれにしても、他のモジュールの共有モジュールとして機能する第3のモジュールを使用すると、実行時に使用できる共通のクラス/機能を持つことができるため、柔軟性が向上します。
コンパイル後に別の操作を行う必要はありません。

+0

私はこれを動作させることができませんでした。私は 'temp.d.ts'の代わりに' pnode.d.ts'を除いてこの答えのように 'value.ts'を書き換え、問題のある実行時依存関係を保っていました。次に、 'tsc --module commonjs --moduleResolution node --declaration pnode.ts'でpnodeをコンパイルして、.d.tsファイルを作成しました。次に、pnode.d.tsから 'export ='行を削除しました。最後に 'tsc --module commonjs --moduleResolution node value.ts'をコンパイルします。しかし、これは '' func'の宣言に ''名前空間 'pnode'を見つけることができませんでした。 –

+0

なぜそれがあなたのために働いていないのか分かりません。どのバージョンのtscを使用していますか?私は '1.8.10'を持っています。 'value.ts'に' pnode'への参照があったとき 'pnode.ts'をコンパイルすることができませんでした。それは'ファイルの値を書き込めません。 d.tsは入力ファイルを上書きするためです。だから私は 'require(pnode)'に変更し、 'pnode'をコンパイルし、' value.ts'を 'pnode.d.ts'を参照するように変更し、(エクスポート行を削除した後で)それを働かせなければなりませんでした。 –

関連する問題