'eslint complains about typescript's path aliasing

I've set up path aliasing in typescript's .tsconfig so my imports look cleaner.

In my code when I try and import my interface like this

import { ApiResponse } from '@api';

eslint complains: Unable to resolve path to module '@api' However, intelisense in vscode seems fine. Its able to give code prediction and "Jump to declaration" which is a clue that my .tsconfig is set up correctly but eslint is somehow misconfigured.


Relevant files

In my tsconfig.json, I've set up path aliasing like so:

{
  "compilerOptions": {
    "moduleResolution": "node",               
    "baseUrl": "./src",                     
    "paths": {                              
      "@api": ["./types/api"]
    },
  }
}

My ./src/types/api.ts looks like this:

// 3rd party API response object
export interface ApiResponse {
  ....
}

Finally, my .eslintrc.json looks like this:

{
  "env": {
    "node": true
  },
  "globals": {
    "console": true
  },
  "plugins": ["@typescript-eslint", "prettier"],
  "parser": "@typescript-eslint/parser",
  "settings": {
    "import/extensions": [".js", ".ts"],
    "import/parsers": {
      "@typescript-eslint/parser": [".ts"]
    },
    "import/resolver": {
      "node": {
        "extensions": [".js", ".ts"]
      }
    }
  }
}


Any idea what I may be doing wrong?



Solution 1:[1]

To support the tsconfig baseUrl and paths, you need the package eslint-import-resolver-typescript.

  1. Make sure to have the basics:
# install the basics
npm i -D @typescript-eslint/parser @typescript-eslint/eslint-plugin

# support tsconfig baseUrl and paths
npm i -D eslint-plugin-import eslint-import-resolver-typescript
  1. Then in the eslintrc, here in json:
{
  "settings": {
    "import/resolver": {
      "typescript": {}
    }
  },
  "parser": "@typescript-eslint/parser",
  "parserOptions": {
    "project": "./tsconfig.json",
    "tsconfigRootDir": "./"
  },
  "plugins": [
    "@typescript-eslint",
    "import"
  ],
  "extends": [
    "plugin:@typescript-eslint/recommended",
    "plugin:@typescript-eslint/recommended-requiring-type-checking"
  ]
}

Solution 2:[2]

I have created react native project with typescript enabled using expo. I have followed the below steps to add path aliasing

folder structure:

folder structure

Steps:

  1. Add baseURL and custom paths in tsconfig.json under compilerOptions as follow:

    "compilerOptions": {
             "allowSyntheticDefaultImports": true,
             "jsx": "react-native",
             "lib": [
             "dom",
             "esnext"
             ],
             "moduleResolution": "node",
             "noEmit": true,
             "skipLibCheck": true,
             "resolveJsonModule": true,
             "strict": true,
             "baseUrl": ".",
             "paths": {
               "*": ["src/*"],
               "$utility/*": ["src/utility/*"], // if /* is not added eslint throwing error so should be added in name and path as well
               "$themes/*": ["./src/themes/*"],
               "$assets/*": ["./src/assets/*"]
             }
         }
    
  2. Add aliases in babel.config.js under 'module-resolver' as follow:

          module.exports = function(api) {
             api.cache(true);
             return {
                 presets: ["babel-preset-expo"],
                 plugins: [
                     [
                       'module-resolver',
                       {
                         root: ["./src"],
                         alias: {
                           "$utility": './src/utility',
                           "$themes": './src/themes',
                           "$assets": './src/assets',
                         },
                       },
                     ],
                 ],
             };
         };
    
  3. Install eslint-plugin-import & eslint-import-resolver-typescript using following command:

    npm i -D eslint-plugin-import eslint-import-resolver-typescript

  4. After installing packages add typescript under import/resolver as below in eslintrc file:

           "settings": {
             "import/core-modules": ["@expo/vector-icons"],
             "import/extensions": [".js", ".jsx", ".ts", ".tsx"],
             "import/parsers": {
               "@typescript-eslint/parser": [".ts", ".tsx"]
             },
             "import/resolver": {
               "typescript": {},
               "node": {
                 "extensions": [".js", ".jsx", ".ts", ".tsx"]
               }
             }
         }
    
  5. Refresh vscode using command + shift + p -> Reload window.

Note: Projects created using expo will have babel-plugin-module-resolver package installed by default so no need to install it again

Solution 3:[3]

I had this problem, and it was trickier since I am using a monorepo structure. resolved that by using eslint-import-resolver-typescript.

As explained in the doc, inside your eslint config, you add this configuration pointing to all your projects.

// inside .eslintrc

"settings": {
  "import/resolver": {
    "typescript": {
      // use an array
      "project": [
        "packages/module-a/tsconfig.json",
        "packages/module-b/tsconfig.json"
      ],
    }
  }
}

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Mouloud88
Solution 2 abhinav
Solution 3