5

There are several questions on how to split TypeScript modules with classes in separate files but so far no solution applied to my issue.

I have one module (store) which includes two classes (Person & SerialisedRecord). When both classes are in one file, the compilation and export works fine.

Now I want to have one file for each class (Person.ts & SerialisedRecord.ts), following the same export schema I already have. But I don't know how to achieve this.

Here is my initial situation:

store.ts

export module store {

  export class Person {
    public fullName: string = '';

    constructor(firstName: string, lastName: string) {
      this.fullName = `${firstName} ${lastName}`;
    }
  }

  export class SerialisedRecord {   
    constructor(public serialised: string, public id: string) {}
  }

}

When I compile store.ts to store.js (ES5), I get exactly what I want (a SystemJS module exporting both classes in one module):

System.register([], function(exports_1, context_1) {
    "use strict";
    var __moduleName = context_1 && context_1.id;
    var store;
    return {
        setters:[],
        execute: function() {
            (function (store) {
                var Person = (function () {
                    function Person(firstName, lastName) {
                        this.fullName = '';
                        this.fullName = firstName + " " + lastName;
                    }
                    return Person;
                }());
                store.Person = Person;
                var SerialisedRecord = (function () {
                    function SerialisedRecord(serialised, id) {
                        this.id = id;
                        this.serialised = serialised;
                    }
                    return SerialisedRecord;
                }());
                store.SerialisedRecord = SerialisedRecord;
            })(store = store || (store = {}));
            exports_1("store", store);
        }
    }
});

Now I tried to do this:

export module store {
  export {Person} from "./Person";
  export {SerialisedRecord} from "./SerialisedRecord";
}

But it fails telling me:

error TS1194: Export declarations are not permitted in a namespace.

Can you tell me what I do wrong?

Here is my tsconfig.json:

{
  "compilerOptions": {
    "module": "system",
    "moduleResolution": "node",
    "noEmitOnError": true,
    "noImplicitAny": false,
    "noImplicitReturns": true,
    "removeComments": true,
    "target": "es5"
  },
  "exclude": [
    "node_modules",
    "typings/browser",
    "typings/browser.d.ts"
  ]
}

1 Answer 1

4

It works great if you remove the store module:

store.ts:

export { Person } from "./Person";
export { SerialisedRecord } from "./SerialisedRecord";

index.ts:

import { Person, SerialisedRecord } from "./store";

let p = new Person("first", "last");

Edit

If you must keep the namespace structure, you can try something like:

import Person from "./Person";
import SerialisedRecord from "./SerialisedRecord";

export default {
    store: {
        Person,
        SerialisedRecord
    }
}
Sign up to request clarification or add additional context in comments.

5 Comments

But then my SystemJS module doesn't contain exports_1("store", store);, which means that my namespace store will not be available when loading my module.
Why do you need it if there's nothing in it?
I want to have it to structure my app into JS namespaces like module.store, module.notification, module.audio and such.
But that approach made sense when all scripts were loaded into the same global namespace, but when you're using a module system then it makes less sense. But check my revised answer.
Ok, this works! :) Very important is that Person and SerialisedRecord use export default class, like export default class Person.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.