ウェブサイト検索

TypeScript の内部モジュールの使用


私はBMW.tsに次のように定義されたBMWというクラスを持っています:

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

module Entities.Cars {

    import e = Entities;

    export class BMW extends Vehicle {

        public series: string;

         constructor ( model : string, series : string) {
            super("BMW", model)
            this.series = series;
        }

         drive() {
             alert("driving a bimmer is a different kind of feeling");
         }       

         toString() : string
         { 
             return this.getName() + " " + this.series + " " + this.getType();
         }
    }
}

別のファイル Thing.ts では、次のように Vehicle クラスと Thing クラスが定義されています:

module Entities {

    // Class
    export class Thing {

        private _name: string;
        private _type: string;

        // Constructor
        constructor (public name: string, public type: string) {
            this._name = name;
            this._type = type;
         }

        getName(): string { return this._name; }
        setName(name: string) { this._name = name; }


        getType(): string { return this._type; }
        setType(name: string) {
            this._type = name;
        }

        toString() : string
        { 
            return "Entities.Thing";        
        }
    }

    export class Vehicle extends Thing {

        public cargoCapacity: number;
        public fuelType: string;
        public owner: string;

        constructor (make: string, model : string) {
            super(make, model)
        }

        drive() {
        }

        toString(): string {
            return "Entities.Vehicle";
        }
    }
}

Thing と BMW の TypeScript ファイルを参照した後、次のコードを実行しようとするとき:

var car = new Entities.Cars.BMW("335i", "E90");
car.drive();

次のエラーで例外が発生します: "Microsoft JScript ランタイム エラー: プロパティ 'BMW' の値を取得できません: オブジェクトが null または未定義です"。BMW のために生成された Javascript にエラーがあります。上記のスニペットのどこが間違っているのでしょうか?

回答 #1

あなたのコードには問題はないので、生成されたjavascriptファイルのインポート順序が間違っているようです。仕様には次のように書かれています:

グローバルモジュールを構成するソースファイルの初期化順序は、最終的には生成されたJavaScriptファイルが実行時に読み込まれる順序に依存します(例えば、生成されたJavaScriptファイルを参照するタグによって制御される場合があります)。

次のように、app.ts というファイルを生成しました:

///<reference path='Things.ts'/>
///<reference path='bmw/BMW.ts'/>
var car = new Entities.Cars.BMW("335i", "E90");
car.drive();

この時点で、あなたには二つの選択肢があります:

  1. コンパイラに、単一の出力ファイルを生成することでファイルを実行する正しい順序を決定させる

    tsc --out app.js app.ts

    それから、app.js を読み込むだけです。

  2. 正しい順序を手動で指定してください。私にとっては、以下の順序だけがエラーを出さずに動作します。

    <html>
        <head>
            <script src="Things.js"></script>
            <script src="bmw/BMW.js"></script>
            <script src="app.js"></script>
        </head>
        <body>
        </body>
    </html>
    

回答 #2

あなたのコードは問題ありません。

私の推測では、あなたはhead要素内にスクリプトタグを正しく配置していないようです(順序が間違っているか、いくつかを省略している可能性があります)。

これを解決する最も簡単な方法は、適切な宣言の順序を覚えておく必要がないように、tscコンパイラーで --out オプションを設定して単一の .js 出力ファイルを使用することです。

編集: どのJSシナリオで作業しているか(WSH、ウェブアプリ、または他のJS環境)によって、JSソースファイルのリンク方法は異なります。例えばWSHの場合、FileSystemObjectを使用してソースファイルを読み込み、それを評価することができます。また、AMDを使用することもできます...