import-js / eslint-plugin-import

ESLint plugin with rules that help validate proper imports.
MIT License
5.51k stars 1.57k forks source link

`import/extensions`, `import/no-unresolved` don't highlight import of nonexistent .js in TypeScript project #3015

Open jwbth opened 3 months ago

jwbth commented 3 months ago

Take this simple setup:

eslint.config.js

import eslint from '@eslint/js';
import tseslint from 'typescript-eslint';
import * as pluginImport from 'eslint-plugin-import';

export default [
  eslint.configs.recommended,
  ...tseslint.configs.recommended,
  {
    files: ['**/*.ts'],
    plugins: {
      'import': pluginImport,
    },
    settings: {
      'import/resolver': {
        node: true,
        typescript: true,
      },
    },
    rules: {
      'import/extensions': 'error',
      'import/no-unresolved': 'error',
    },
  },
];

index.ts

import { num } from './exported.js';

exported.ts

export const num = 3;

In index.ts, ./exported.js points to a nonexistent file. Neither import/extensions, nor import/no-unresolved highlight it though.

I narrowed down the problem to typescript: true – as soon as I comment that line, I see both errors:

Unexpected use of file extension "js" for "./exported.js" eslint(import/extensions) Unable to resolve path to module './exported.js'. eslint(import/no-unresolved)

I assume it may be something to do with the eslint-import-resolver-typescript package, so I tried messing with it in some ways, but to no avail.

ljharb commented 3 months ago

try changing

      'import/resolver': {
        node: true,
        typescript: true,
      },

to:

      'import/resolver': {
        typescript: true,
        node: true,
      },
jwbth commented 3 months ago

No effect, unfortunately.

jwbth commented 3 months ago

I should also note that the highlight will appear also if:

So, this seems to be a pretty unique case with a nonexistent .js silently mapping to an existent .ts with the same basename.

dmitryshelomanov commented 3 months ago

@ljharb did you solve it ?

alexgwolff commented 2 months ago

try changing

      'import/resolver': {
        node: true,
        typescript: true,
      },

to:

      'import/resolver': {
        typescript: true,
        node: true,
      },

This works to me

ljharb commented 2 months ago

Certainly you'd basically always want node to be last in that object.