marc08 marc08 - 23 days ago 13
TypeScript Question

Typescript and AngularJS 1.5: How to handle export class

I have this module.ts file:

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);


and this gets transpiled/compiled to 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);


The problematic line is: exports.ProductService = ProductService; If i remove this manually - the app works perfectly. But if i leave this like that, in the browsers console i get an error "exports is not defined".
What can be done about this? I cant just remove "export" from the .ts file as this class is used in other files (i import it there). I tried different compiler options, but it just gives me different errors (like "define is not defined" etc) and im not sure how to handle this.. maybe theres a way that the tsc would just not produce this line?

Thank you for any help!

Answer

Whenever you use the import and export keywords in typescript, you are converting the file to act as a module.

Modules are designed to work along with module systems like commonjs,amd, es6, systemjs etc....

If your are trying to load a raw script in a browser without using a module-lodaer or bundler such as systemjs, webpack, browserify, jspm, etc.... then you cannot use external modules (so you can't use import/exports).

You can still use typings from definitely typed, but you have to load them throught ///<reference /> tags.

If using typescript 2.0 typings like angular are also available and imported by default when you run

npm install @types/angular

Usually these typings will expose global namespace declaration that you will now be able to use thorughout your application.

For example in your case angular exposes an ng namespace and you would use it like:

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

You can also easily alias it:

import IPromise = ng.IPromise

Note that this import behaves differently than module imports (it just aliases).

If you are going to do anything other than a trivial application, I would strongly recommend you use a module loader such as webpack to compile and bundle the application for the browser. There are many limitations to just using plain scripts.