13

I had a jsconfig.json which I replaced with a tsconfig.json. Following the replacement, VSCode doesn't pick up path aliases and reports an import error:

Example:

Cannot find module '@Components/Title' or its corresponding type declarations.ts(2307)

jsconfig.json

// https://code.visualstudio.com/docs/languages/jsconfig

{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@Components/*": ["./src/components/*"],
            "@Modules/*": ["./src/modules/*"],
            "@Styles/*": ["./src/styles/*"],
            "@Content/*": ["./src/content/*"],
            "@Apps/*": ["./src/apps/*"]
        }
    },
    //Add any build/compiled folders here to stop vscode searching those
    "exclude": ["node_modules", "build"]
}

tsconfig.json

// https://code.visualstudio.com/docs/languages/jsconfig
{
    "compilerOptions": {
        "baseUrl": ".",
        "paths": {
            "@Components/*": ["./src/components/*"],
            "@Modules/*": ["./src/modules/*"],
            "@Styles/*": ["./src/styles/*"],
            "@Content/*": ["./src/content/*"],
            "@Apps/*": ["./src/apps/*"]
        },
        "target": "es5",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "strict": false,
        "forceConsistentCasingInFileNames": true,
        "noEmit": true,
        "incremental": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "isolatedModules": true,
        "jsx": "preserve"
    },
    "exclude": ["node_modules", "build"],
    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

Update 1: I only have this issue with files ending in .js. If I rename them to .ts everything works fine. Weirdly enough, if I rename the file back to .js and restart VSCode, the errors don't show up in the file anymore.

bluprince13
  • 4,607
  • 12
  • 44
  • 91

3 Answers3

21

The tsconfig configuration will only apply to files matched by the "include" option and not excluded by the "exclude" option. Your "include" option only matches .ts and .tsx files, but not .js files

Add "**/*.js" to the list of included globs and it should work.

Jeffrey Maxwell
  • 304
  • 3
  • 7
  • 2
    I have added this pattern to tsconfig.spec.json and nothing is changed. What can go wrong? – Vadim Aug 03 '22 at 10:45
  • BTW, this may be a different question: because relative paths are not visible in my project based on angular 13 (the same error) – Vadim Aug 03 '22 at 11:13
2

The problem is that TypeScript's compiler preserves the paths as they are written in the source, as you can see in this GitHub issue, which makes tsc unusable for your use case.

As you are apparently building a web application, I'll provide a minimal solution based on Webpack, one of the most popular bundlers for the web.

.
├── src
│   ├── components
│   │   └── component.ts
│   └── index.ts
├── package.json
├── tsconfig.json
└── webpack.config.js

src/index.ts

import { Component } from '@Components/component';
Component.log();

src/components/component.ts

export class Component {
    static log() {
        console.log("test");
    }
}

package.json

{
  "name": "70072923",
  "version": "1.0.0",
  "description": "",
  "main": "src/index.js",
  "devDependencies": {
    "ts-loader": "^9.2.6",
    "tsconfig-paths-webpack-plugin": "^3.5.2",
    "typescript": "^4.5.2",
    "webpack": "^5.64.4",
    "webpack-cli": "^4.9.1"
  },
  "scripts": {
    "build": "webpack",
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "license": "ISC"
}

tsconfig.json

{
    "compilerOptions": {
        "baseUrl": "src",
        "paths": {
            "@Components/*": ["components/*"],
        },
        "target": "es5",
        "lib": ["dom", "dom.iterable", "esnext"],
        "allowJs": true,
        "skipLibCheck": true,
        "strict": false,
        "forceConsistentCasingInFileNames": true,
        "incremental": true,
        "esModuleInterop": true,
        "module": "esnext",
        "moduleResolution": "node",
        "resolveJsonModule": true,
        "jsx": "preserve"
    },
    "exclude": ["node_modules", "build"],
    "include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"]
}

webpack.config.js

const path = require('path');
const TsconfigPathsPlugin = require('tsconfig-paths-webpack-plugin');

module.exports = {
    entry: './src/index.ts',
    resolve: {
        extensions: ['.ts'],
        plugins: [
            new TsconfigPathsPlugin,
        ]
    },
    output: {
        filename: 'bundle.js',
        path: path.resolve(__dirname, 'dist'),
    },
};

Build the project with npm run build, which outputs a single minimal self-contained file ready to execute:

dist/bundle.js

(()=>{"use strict";(class{static log(){console.log("test")}}).log()})();

Full project here: https://github.com/Guerric-P/Webpack-and-TypeScript-path-mappings

Guerric P
  • 30,447
  • 6
  • 48
  • 86
  • Appreciate you taking the time to explain. I'm sorry I didn't make my question clearer though - I'm not having any problem executing my code. The error I get is purely on VSCode when I look at the file. – bluprince13 Nov 28 '21 at 23:01
  • I did realise something from your package though. You have given your `index` file a `.ts` ending. VSCode recognises `'@Components/component'` whilst this is the case. However, if I change the file ending to `.js` it throws the same error! – bluprince13 Nov 28 '21 at 23:06
  • You'll never be able to import a TypeScript module in a JavaScript module because JavaScript doesn't know TypeScript at all. As TypeScript is a superset of JavaScript, any JavaScript file is valid as TypeScript (as long as you didn't set options like `noImplicitAny`, `noImplicitReturns`, etc.) so the best thing you could do is rename all of your `.js` files to `.ts` instead of having an hybrid project like you seem to have. – Guerric P Nov 29 '21 at 10:54
0

In my case, the aliases can not be read by vs code on Jest extension during the test but there is no problem with yarn test.

FAIL  src/components/main/index.spec.tsx
  ● Test suite failed to run

    Cannot find module '@test' from 'src/components/main/index.spec.tsx'

    > 1 | import { render } from "@test";
        | ^
      2 |
      3 | import { Main } from "./index";
      4 |

The solution is add a settings.json in .vscode folder ar root directory:

// .vscode/settings.json
{
  "jest.jestCommandLine": "yarn test"
}
yohanes
  • 2,365
  • 1
  • 15
  • 24