Reputation: 7664
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.
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?
Upvotes: 74
Views: 63312
Reputation: 755
It seems that @typescript-eslint
now support path aliases.
I used to have many "Unsafe argument of type any
assigned to a parameter of type string
" errors
when using types coming from path aliases (using tsconfig's paths
option)
but it was due to a misconfiguration of my parserOptions.project
option.
Here is my project tree & working configuration (if it can help):
.
├── e2e/
│ ├── .eslintrc.js
│ └── tsconfig.json
├── src/
│ ├── app/
│ └── libs/
├── .eslintrc.js
├── tsconfig.base.json
├── tsconfig.eslint.json
└── tsconfig.json
// tsconfig.json
{
"extends": "./tsconfig.base.json",
"compilerOptions": {
...,
"paths": {
"@foo/angular/*": ["./src/libs/modules/*"],
"@foo/test/*": ["./src/libs/test/*"],
"@foo/utils/*": ["./src/libs/utils/*"]
}
},
...
}
// tsconfig.eslint.json
{
"extends": "./tsconfig.json",
"include": ["src/**/*.ts", "e2e/**/*.ts"]
}
// .eslintrc.js
var config = {
root: true,
ignorePatterns: ['projects/**/*'],
overrides: [
{
files: ['*.ts'],
excludedFiles: ['node_modules/**/*'],
extends: [
'eslint:recommended',
'plugin:@typescript-eslint/recommended',
'plugin:@typescript-eslint/stylistic',
...
],
parserOptions: {
project: ['tsconfig.eslint.json'],
},
rules: { ... },
},
],
};
// e2e/tsconfig.json
{
"extends": "../tsconfig.base.json",
"compilerOptions": {
...,
"paths": {
"@foo/auth/*": ["./src/libs/modules/auth/*"],
"@foo/utils/*": ["./src/libs/utils/*"],
"@my-app/*": ["./src/app/modules/*"]
}
},
"include": ["src/**/*.ts"]
}
// e2e/.eslintrc.js
var config = {
ignorePatterns: ['!**/*'],
extends: ['../.eslintrc.js', 'plugin:cypress/recommended'],
parserOptions: {
project: ['e2e/tsconfig.json'],
},
rules: { ... },
};
Thus I don't have to rely on an additional eslint-import-resolver-typescript
lib
or its dependencies eslint-plugin-import
/ eslint-plugin-import-x
, which may be problematic [1] [2].
Upvotes: 0
Reputation: 136
I have created react native project with typescript enabled using expo. I have followed the below steps to add path aliasing
folder structure:
Steps:
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/*"]
}
}
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',
},
},
],
],
};
};
Install eslint-plugin-import & eslint-import-resolver-typescript using following command:
npm i -D eslint-plugin-import eslint-import-resolver-typescript
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"]
}
}
}
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
Upvotes: 8
Reputation: 51
My project is an electron app set up using the electron forge webpack-typescript template, I also added React to the project. I fixed this issue by:
eslint-import-resolver-typescript
as a dev dependency.eslintrc.json
to include:"settings": {
"import/resolver": {
"typescript": {}
}
}
Upvotes: 2
Reputation: 2220
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"
],
}
}
}
Upvotes: 29
Reputation: 141542
To support the tsconfig baseUrl
and paths
, you need the package eslint-import-resolver-typescript
.
# 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
{
"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"
]
}
Upvotes: 129