4

I am working with Angular 11 and trying to use short imports like import {smthg} from '@common' instead of import {smthg} from '../../../common'

But I always get errors in IDEA: TS2307: Cannot find module '@common' or its corresponding type declarations.

And same error in console when trying to compile .ts files (ng serve)

Interestingly, when I add /index to the import, then IDEA stops cursing, but the error does not disappear in the console

myAngularProject
│   package.json
│   tsconfig.json
│   tsconfig.app.json
│   angular.json    
│
└───src
    │   main.ts
    │   index.html
    │
    └───app
        │  
        └───common
        │
        └───features

tsconfig.json:

/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
  "compileOnSave": false,
  "compilerOptions": {
    "baseUrl": "./src",
    "paths": {
      "@common/*": ["app/common/*"],
      "@features/*": ["app/features/*"],
      "@platform/*": ["app/platform/*"],
      "@env": ["environments/environment"]
    },
    "outDir": "./dist/out-tsc",
    "forceConsistentCasingInFileNames": true,
    "strict": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true,
    "sourceMap": true,
    "declaration": false,
    "downlevelIteration": true,
    "experimentalDecorators": true,
    "moduleResolution": "node",
    "importHelpers": true,
    "target": "es2015",
    "module": "es2020",
    "lib": [
      "es2018",
      "dom"
    ]
  },
  "angularCompilerOptions": {
    "strictInjectionParameters": true,
    "strictInputAccessModifiers": true,
    "strictTemplates": true
  }
}

tsconfig.app.json:

{
  "extends": "./tsconfig.json",
  "compilerOptions": {
    "outDir": "./out-tsc/app",
    "types": ["node"]
  },
  "files": [
    "src/main.ts",
    "src/polyfills.ts"
  ],
  "include": [
    "src/**/*.d.ts"
  ]
}

IDEA error: idea error

console tsc error: enter image description here

Versions:

Angular CLI: 11.0.7
Node: 14.2.0
OS: darwin x64

Angular: 11.0.9
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Ivy Workspace: Yes

Package                         Version
---------------------------------------------------------
@angular-devkit/architect       0.1100.7
@angular-devkit/build-angular   0.1100.7
@angular-devkit/core            11.0.7
@angular-devkit/schematics      11.0.7
@angular/cli                    11.0.7
@schematics/angular             11.0.7
@schematics/update              0.1100.7
rxjs                            6.6.3
typescript                      4.0.5
kerm
  • 653
  • 1
  • 5
  • 15
  • 1
    The Angular compiler doesn't support `paths` as far as I am aware. Definitely annoying... – Aluan Haddad Jan 22 '21 at 16:32
  • 1
    thanks for this terrible news ( looks like the truth. well, it seems the only way is to give up angular CLI and use webpack. – kerm Jan 23 '21 at 19:42
  • 1
    I would have recommended that approach a year or so ago, but there is such a plethora of documentation that presumes the CLI as well as tooling built on top of it, such as the Ionic CLI, that it is a decision you should make circumspectly. I'm not saying it's the wrong one, as I particularly hate so many layered tooling abstractions that don't let you get at the internals when you need them, but consider carefully. Good luck. – Aluan Haddad Jan 23 '21 at 19:47

6 Answers6

10

So it turned out that the angular engine allows creating aliases for paths based on what is specified in the "paths" in tsconfig.

But in order to be able to access both the subfolders of the module and what is exported from the index.ts at the top level of the module, you need to specify "paths" like this:

{
  ...
  "compilerOptions": {
    "baseUrl": "src",
    "paths": {
      "@common/*": ["app/common/*"],
      "@common": ["app/common/index.ts"]
    }
  ...
  }
}
kerm
  • 653
  • 1
  • 5
  • 15
5

I had the same issue. I was trying to migrate a project made with Angular 10 to Angular 11, coping the ./src/app folder, but that didn't work...

But in a new project, I got the path aliasing working in that way:

  • Update your angular cli:
PS C:\Projects> npm uninstall --g @angular/cli
PS C:\Projects> npm i --g @angular/cli
  • Create a new project, setting the strict mode to true:
PS C:\Projects> ng new <<name-project>>
PS C:\Projects> cd <<name-project>>
  • When the CLI ends, edit tsconfig.app.json as follows:
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
    "extends": "./tsconfig.json",
    "compilerOptions": {
        "outDir": "./out-tsc/app",
        "types": [],

        // ADD THIS ↓↓↓
        "baseUrl": "./",
        "paths": {
            "@tool/*": [ "src/app/tool/*" ],
            "@models/*": [ "src/app/models/*" ],
            "@services/*": [ "src/app/services/*" ],
            "@components/*": [ "src/app/components/*" ],
            "@interfaces/*": [ "src/app/interfaces/*" ]
        }
        // ADD THIS ↑↑↑
    },
    "files": [
        "src/main.ts",
        "src/polyfills.ts"
    ],
    "include": [
        "src/**/*.d.ts"
    ]
}
  • ...and tsconfig.json as follows:
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
    "compileOnSave": false,
    "compilerOptions": {
        "outDir": "./dist/out-tsc",
        "forceConsistentCasingInFileNames": true,
        "strict": true,
        "noImplicitReturns": true,
        "noFallthroughCasesInSwitch": true,
        "sourceMap": true,
        "declaration": false,
        "downlevelIteration": true,
        "experimentalDecorators": true,
        "moduleResolution": "node",
        "importHelpers": true,
        "target": "es2015",
        "module": "es2020",
        "lib": [
            "es2018",
            "dom"
        ],

        // ADD THIS ↓↓↓
        "baseUrl": "./",
        "paths": {
            "@tool/*": [ "src/app/tool/*" ],
            "@models/*": [ "src/app/models/*" ],
            "@services/*": [ "src/app/services/*" ],
            "@components/*": [ "src/app/components/*" ],
            "@interfaces/*": [ "src/app/interfaces/*" ]
        }
        // ADD THIS ↑↑↑
    },
    "angularCompilerOptions": {
        "enableI18nLegacyMessageIdFormat": false,
        "strictInjectionParameters": true,
        "strictInputAccessModifiers": true,
        "strictTemplates": true
    }
}
  • ...and finally, edit tsconfig.spec.json as follows:
/* To learn more about this file see: https://angular.io/config/tsconfig. */
{
    "extends": "./tsconfig.json",
    "compilerOptions": {
        "outDir": "./out-tsc/spec",
        "types": [
            "jasmine"
        ],
        "baseUrl": "./",
        "paths": {
            "@tool/*": [ "src/app/tool/*" ],
            "@models/*": [ "src/app/models/*" ],
            "@services/*": [ "src/app/services/*" ],
            "@components/*": [ "src/app/components/*" ],
            "@interfaces/*": [ "src/app/interfaces/*" ]
        }
    },
    "files": [
        "src/test.ts",
        "src/polyfills.ts"
    ],
    "include": [
        "src/**/*.spec.ts",
        "src/**/*.d.ts"
    ]
}
SleepWritten
  • 334
  • 2
  • 5
1

This one worked for me in Angular 13, Don't miss the dot (.) in each path value.

"baseUrl": "./",
"paths": {
      "@app/*": [
        "./src/app/*"
      ],
      "@env/*": [
        "./src/environments/*"
      ]
    }
Midhun KM
  • 1,647
  • 1
  • 21
  • 31
0

First of all you need to restart your code editor to make sure it's not a problem with your linter.

I had similar problem and in my case configs were correct, though I didn't know that at that time due to the lack of experience so I kept on trying different solutions I could find. It turned out the problem was with the linter not being able to see config changes (added path definitions) until IDE restart.

Kane Shynin
  • 71
  • 1
  • 7
  • `If nothing helps` You mean after trying these solutions? Because if you did try them, then it's likely that this is what fixed the issue -after restarting the editor-, not just magically the fact of restarting it. Please add details to your answer. Thanks. – Eric Aya Jun 13 '21 at 10:39
0

Path aliases are not longer supported in newer versions

But you can do this now to directly import files relative to the src directory

go to your tsconfig.json file add baseUrl to be "."

"compilerOptions": {
    "baseUrl":".",
    ...

And now you can directly import stuff relative to the src directory

import Myfile from "src/myfile.js"

This worked for me!

Abraham
  • 12,140
  • 4
  • 56
  • 92
0

In my case the path aliasing was actually working, but I was missing a .ts file in the folder, so the types were not recognized. Same error, though: "Cannot find module @app or its corresponding type declarations"

Markus
  • 1,020
  • 14
  • 18