Thursday, 27 April 2017

Create Module containing all exports in TypeScript

What am I trying to achieve

I am trying to create a module in TypeScript which would contain every export of needed classes. In fact, what bothers me actually is to have import statements in my classes which are all relative, which is not really the best way for further maintenances. I would like to use absolute paths only.

Once transpiled, classes (in the produced JavaScript) with absolute paths have wrong paths (since they are not translated to relative paths, and even worse when used in conjunction with tsconfig.json > outDir option).

Example usage

Let's start with the following hierarchy of project as example

root
|- helpers
   |- MyHelper.ts
   |- AnotherHelper.ts
|- calculators
   |- MyCalc.ts
|- parsers
   |- XmlParser.ts
   |- JsonParser.ts
|- index.ts // currently holding export statements

What I want to do

I would like to have an index.ts file of this kind :

// a top-level module, resolved like the `node` strategy of NodeJS module resolution
export module IndexModule {
    export { MyHelper } from "./helpers/MyHelper";
    export { AnotherHelper } from "./helpers/AnotherHelper";
    // do the same for every class in my project
}

So then I could do the following :

import { JsonParser } from "IndexModule"; // no relative nor absolute path

export class MyHelper {
    public constructor(input: any){
       var result: any = new JsonParser().parse(input);
       // work with result ...
    }
}

I've seen in many places (here on SO, the github repo of TypeScript, ...) that I am not the only one struggling with relative/absolute paths for imports.

My actual question is : Is it possible to create such a module (or mechanic) so I can define every export in a top container, and import this container as if I was using a NodeJS module (like import * as moment from "moment") ?

What I tried

First try

This is the index.ts file I actually have :

// index.ts is in the root directory of the project, it accesses classes with relative paths (but here, management is quite easy)
export { Constants } from "./helpers/Constants";
export { ConstraintCalculatorHelper } from "./helpers/ConstraintCalculatorHelper";
export { MomentHelper } from "./helpers/MomentHelper";
export { Formatter, OutputFormatterHelper } from "./helpers/OutputFormatterHelper";
// ... doing this for each class I have in my project

Second try

declare module IndexModule {
    export { Constants } from "./helpers/Constants";
    export { ConstraintCalculatorHelper } from "./helpers/ConstraintCalculatorHelper";
    export { MomentHelper } from "./helpers/MomentHelper";
    export { Formatter, OutputFormatterHelper } from "./helpers/OutputFormatterHelper";
    // error : Export declarations are not permitted in a namespace
}

Third, Fourth, N-th try

Tried to declare namespace, export module, etc etc .. without luck.

Tried to declare module "IndexModule too, leads to an error : Import or export declaration in an ambient module declaration cannot reference module through relative module name

Side note

I am not an expert in NodeJS / Modules / Namespaces, so I maybe have not understood something well. If so, I would appreciate if someone can point out what I misunderstood.

Relevant link here that shows the actual problem.

Configuration :

  • NodeJS v7.2
  • TypeScript v2.2

tsconfig.json :

{
  "compileOnSave": true,
  "compilerOptions": {
    "removeComments": false,
    "sourceMap": true,
    "module": "commonjs",
    "target": "es6",
    "noImplicitAny": false,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "experimentalDecorators": true,
    "emitDecoratorMetadata": true,
    "outDir": "./bin/LongiCalc"
  }
}



via Jacks

No comments:

Post a Comment