Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeScript declare module

I want to create local modules in my TypeScript (with Angular 2) app and then simple reference to any file with importing module like myApp/components, myApp/pipes etc., not using relative path (../../../MyComponent) as I have to do now.

For instance, Angular 2 can be used like this. (And I haven't found how they make it)

import {Component} from 'angular2/core';

How can I achieve this behavior?


I did some files like components.ts, templates.ts etc. where I export files from current section:

export * from './menu/item';
export * from './menu/logo';
export * from './article/article';
export * from './article/sidebar';

... and then I have one main file myApp.ts where I declare modules like so:

declare module 'myapp/components' {
    export * from './application/components';
}

declare module 'myapp/templates' {
    export * from './application/templates';
}

But this file doesn't generate anything so TS build tells me errors like ...file_path...(4,9): error TS2305: Module ''myapp/components'' has no exported member 'AlfaBeta'.

Btw. my tsconfig.json looks like this:

{
    "compilerOptions": {
        "target": "ES5",
        "module": "system",
        "moduleResolution": "node",
        "sourceMap": true,
        "emitDecoratorMetadata": true,
        "experimentalDecorators": true,
        "removeComments": false,
        "noImplicitAny": false
    },
    "exclude": [
        "node_modules"
    ]
}
like image 676
tenhobi Avatar asked Jan 28 '16 15:01

tenhobi


1 Answers

In TypeScript 2.0+ there is a baseUrl and paths property in tsconfig.json that you can use.

In your case, you would want:

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "myapp/components": [
                "menu/item",
                "menu/logo",
                "article/article",
                "article/sidebar",
            ],
            "myapp/templates": [
                "templates/*" // whatever files you want to include
            ]
        }
        // etc...
    },
    // etc...
}

In baseUrl you can specify the base directory (usually the root directory of the project). This allows you to do imports from anywhere in the directory structure as if you were doing an import from the directory specified in baseUrl.

For example, with the directory structure...

folder1
    - folder2
        - file2.ts
file1.ts

...specifying a "baseUrl": "." would allow you to import file1.ts in file2.ts as if you were in the root directory by doing:

import * as File1 from "file1"; 

On top of baseUrl you can add paths. This is useful for you and it must be used with a baseUrl. In paths you can specify patterns to match and a list of files to include in that pattern. This is illustrated in the github issue like so:

"paths": {
    "pattern-1": ["list of substitutions"],
    "pattern-2": ["list of substitutions"],
    ...
    "pattern-N": ["list of substitutions"]
}

Note that this will just make it compile. I believe you'll also have to configure SystemJS in order to get this to work at runtime and that might require using a barrel file and setting the path to point to the barrel files.

You can read more about this in the github issue or read my other related answer here that also shows a pre TS 2.0 solution.

like image 78
David Sherret Avatar answered Sep 23 '22 03:09

David Sherret