Search code examples
classtypescriptmoduleexportsystemjs

Export a TypeScript module with classes from different files


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"
  ]
}

Solution

  • 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
        }
    }