網站搜尋

javascript - Typescript 與 AngularJS 1.5:如何處理 export class


我有這個 module.ts 檔案:

import { IHttpService, IPromise } from 'angular';

export class ProductService {
    static $inject = ["$http"];
    constructor(private $http: IHttpService) { }

    loaded: boolean = false;
    promise: IPromise<{ data: any }>;

    getProducts(): IPromise<{ data: any }> {
        if (!this.loaded) {
            this.loaded = true;
            this.promise = this.$http.get('/products.json');
        }
        return this.promise;
    }
}

var module = angular.module("psShopping", ["ngComponentRouter"]);
module.value("$routerRootComponent", "shoppingApp");
module.service('products', ProductService);

而這會被轉譯/編譯成 module.js:

"use strict";
var ProductService = (function () {
    function ProductService($http) {
        this.$http = $http;
        this.loaded = false;
    }
    ProductService.prototype.getProducts = function () {
        if (!this.loaded) {
            this.loaded = true;
            this.promise = this.$http.get('/products.json');
        }
        return this.promise;
    };
    ProductService.$inject = ["$http"];
    return ProductService;
}());
exports.ProductService = ProductService;
var module = angular.module("psShopping", ["ngComponentRouter"]);
module.value("$routerRootComponent", "shoppingApp");
module.service('products', ProductService);

出問題的程式碼行是:exports.ProductService=ProductService; 如果我手動移除這行程式碼,應用程式就能完美運行。但如果我保留這行程式碼,在瀏覽器的控制台會出現錯誤「exports is not defined」。這該怎麼辦呢?我不能只是從 .ts 檔案中移除「export」,因為這個類別在其他檔案中仍有使用(我在那裡有 import 它)。我嘗試過不同的編譯選項,但結果只是出現不同的錯誤(例如「define is not defined」等等),而我不確定該如何處理。也許有辦法讓 tsc 不產生這行程式碼?

答案#1

每當你在 TypeScript 中使用 import 和 export 關鍵字時,你就是將該檔案轉換為模組使用。

模組被設計用來與模組系統一起工作,如 commonjs、amd、es6、systemjs 等等...

如果您嘗試在瀏覽器中加載原始腳本,而不使用像 systemjs、webpack、browserify、jspm 等模組加載器或打包工具,那麼您不能使用外部模組(所以您不能使用 import/export)。

你仍然可以使用來自 DefinitelyTyped 的型別定義,但你必須通過 ///<reference /> 標籤來加載它們。

如果使用 TypeScript 2.0,像 Angular 這樣的型別定義也可以使用,並且當你執行時會自動導入

npm install @types/angular

通常這些型別定義會公開全域命名空間宣告,現在你將能在整個應用程式中使用它們。

例如在你的情況下,Angular 暴露了一個 ng 命名空間,你可以這樣使用它:

  promise: ng.IPromise<{ data: any }>;

你也可以輕鬆地為它取別名:

import IPromise = ng.IPromise

請注意,這個導入的行為與模組導入不同(它只是建立別名)。

如果你打算做任何非簡單的應用,我強烈建議你使用像 webpack 這樣的模組加載器來編譯和打包瀏覽器應用。僅使用普通腳本有很多限制。