Skip to content

Not working with typescriptEslint.configs.recommendedTypeChecked #447

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
2 tasks done
drwpow-figma opened this issue Nov 8, 2024 · 9 comments
Open
2 tasks done

Comments

@drwpow-figma
Copy link

Before You File a Bug Report Please Confirm You Have Done The Following...

  • I have tried restarting my IDE and the issue persists.
  • I have updated to the latest version of the packages.

What version of ESLint are you using?

9.14.0

What version of eslint-plugin-astro are you using?

1.3.1

What did you do?

When using typescript-eslint’s typechecked preset, linting throws an error and doesn’t run.

// eslint.config.js
import eslint from "@eslint/js";
import eslintPluginAstro from "eslint-plugin-astro";
import tseslint from "typescript-eslint";

export default tseslint.config(
  eslint.configs.recommended,

  // this fails:
  ...tseslint.configs.recommendedTypeChecked,

  // this works, if above is commented, and this is used instead:
  // ...tseslint.configs.recommended,

  ...eslintPluginAstro.configs.recommended
);

What did you expect to happen?

Lint run completes

What actually happened?

Oops! Something went wrong! :(

ESLint: 9.14.0

Error: Error while loading rule '@typescript-eslint/await-thenable': You have used a rule which requires type information, but don't have parserOptions set to generate type information for this file. See https://typescript-eslint.io/getting-started/typed-linting for enabling linting with type information.
Parser: astro-eslint-parser
Note: detected a parser other than @typescript-eslint/parser. Make sure the parser is configured to forward "parserOptions.project" to @typescript-eslint/parser.
Occurred while linting /astro-eslint-repro/src/components/Card.astro
    at throwError (/astro-eslint-repro/node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js:38:11)
    at getParserServices (/astro-eslint-repro/node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@typescript-eslint/utils/dist/eslint-utils/getParserServices.js:27:9)
    at create (/astro-eslint-repro/node_modules/.pnpm/@[email protected]_@[email protected][email protected][email protected]/node_modules/@typescript-eslint/eslint-plugin/dist/rules/await-thenable.js:49:55)
    at Object.create (/astro-eslint-repro/node_modules/.pnpm/@[email protected][email protected][email protected]/node_modules/@typescript-eslint/utils/dist/eslint-utils/RuleCreator.js:31:20)
    at createRuleListeners (/astro-eslint-repro/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/linter/linter.js:943:21)
    at /astro-eslint-repro/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/linter/linter.js:1068:84
    at Array.forEach (<anonymous>)
    at runRules (/astro-eslint-repro/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/linter/linter.js:999:34)
    at #flatVerifyWithoutProcessors (/astro-eslint-repro/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/linter/linter.js:1911:31)
    at Linter._verifyWithFlatConfigArrayAndWithoutProcessors (/astro-eslint-repro/node_modules/.pnpm/[email protected]/node_modules/eslint/lib/linter/linter.js:1992:49)

Link to Minimal Reproducible Example

https://github.com/drwpow-figma/astro-eslint-repro

Additional comments

Thanks for a great plugin! ❤️

@ghchaosfae
Copy link

The type checked rules require the projectService (or older project) option to be set.

Add this to your config array:

	{
		languageOptions: {
			parserOptions: {
				projectService: {
					allowDefaultProject: ["*.astro", "*.js"],
				},
				tsconfigRootDir: import.meta.dirname,
			},
		},
	},

Bad news:

If you're experience matches mine, it doesn't actually work to lint .astro files. I get Parsing error: Type expected at the first JSX.

I have yet to figure out how to have both working at the same time.

@drwpow
Copy link

drwpow commented Nov 12, 2024

Ah @ghchaosfae I did see that error as well! But I didn’t know if I was moving “forward” or “backward” so-to-speak. Wanted to find the most minimal issue, and work from there. But to your point, likely a different error happens when we move past the first step, if we determine that’s the right fix.

@ghchaosfae
Copy link

Ok! Update to this, it seems that it's very specifically projectService that causes this failure. projectService is the recommended and new option superseding project (ref: https://typescript-eslint.io/packages/parser#project). If you use project: true, in place of

				projectService: {
					allowDefaultProject: ["*.astro", "*.js"],
				},

it seems to work properly.

For the maintainers: seems like we need some conditional handling somewhere so that the newer property can work?

@drwpow
Copy link

drwpow commented Dec 21, 2024

@ghchaosfae great find! Yes that’s a good workaround, but would love to keep using projectService if possible, because like you said that’s what ESLint recommends (and seems to be the “happy path” going forward)

@martinburger
Copy link

I ran into the same problem when I started using the eslint-config-love package.

It includes projectService: true in the shared configuration, which causes similar problems.

My current workaround is to programmatically delete languageOptions in eslint.config.mjs, which seems more like a hack than a workaround:

import configLove from 'eslint-config-love'
delete configLove.languageOptions

@in-in
Copy link

in-in commented Jan 4, 2025

The problem is still here.
25004193218

Only now the parser tries to use the old project option itself instead of the new one, but it still doesn't work in my case.

`astro-eslint-parser` does not support the `projectService` option, it will parse it as `project: true` instead.

@AndreaPontrandolfo
Copy link

Did you guys try the extrafileextensions option ?

Also related.

@lostfictions
Copy link

lostfictions commented Jan 8, 2025

I hit the same issue -- I'm still seeing Parsing error: Type expected when I try to lint files. The same ESLint config was working fine before I converted it to the flat config format, so I think it might have something to do with how options get merged in the legacy config format compared to the new flat config format.

It looks like if you've got a configuration that sets projectService upstream in the config chain, eslint-plugin-astro will error out. To make things work, within the Astro config projectService needs to be set to false, and project needs to be set explicitly to true. What's more, it seems like this needs to happen in two different parts of the Astro config:

  • The parser for astro files (which invokes typescript-eslint as a sub-parser)
  • The parser for "virtual" script files.

See this plugin's base.ts config for details.

Here's what fixed it for me:

import config from "my-custom-eslint-config-with-typechecked-rules";
import astro from "eslint-plugin-astro";

const ts = "typescript-eslint/parser";

export default [
  ...config,
  ...astro.configs.recommended.map((c) => {
    const opts = c.languageOptions;
    const baseParser = opts?.parser?.meta?.name;
    const subParser = opts?.parserOptions?.parser?.meta?.name;

    if (opts && (baseParser === ts || subParser === ts)) {
      opts.parserOptions = {
        ...opts.parserOptions,
        projectService: false,
        project: true,
      };
    }

    return c;
  }),
];

This makes linting work in frontmatter code blocks, as well as in components. The only part that doesn't seem to work is client <script> tags nested in components.

As a workaround, instead of having the script inline in the component:

<!-- my-component.astro -->
<div>
  <script>
    const neverUsedVar = 5; // won't be linted!
    doCoolStuff();
  </script>
<div>

define them in a separate file and use the script src attribute:

<!-- my-component.astro -->
<div>
  <script src="./do-cool-stuff.ts"></script>
<div>

Ultimately I agree that it would be great if projectService were supported out of the box, but hopefully this should unblock some use cases!

@jpenna
Copy link

jpenna commented May 28, 2025

I spent a lot of time trying a lot of things to make ESLint work seamlessly with Astro.
I will share my configuration here:

// tsconfig.eslint.json
{
  "extends": "./tsconfig.json",
  "include": [".astro/types.d.ts", "src/**/*", "./eslint.config.js", "./astro.config.mjs"]
}
// tsconfig.json
{
  "extends": "astro/tsconfigs/strictest",
  "compilerOptions": {
    "plugins": [
      {
        "name": "@astrojs/ts-plugin"
      }
    ],

    "baseUrl": ".",
    "paths": {
      "@components/*": ["src/components/*"],
      "@layouts/*": ["src/layouts/*"],
      "@pages/*": ["src/pages/*"],
      "@utils/*": ["src/utils/*"],
      "@i18n/*": ["src/i18n/*"],
      "@assets/*": ["src/assets/*"],
      "@styles/*": ["src/styles/*"],
      "@websites/*": ["src/pages/_landingPages/websites/*"]
    },

    /* Linting */
    "strict": true,
    "noUnusedLocals": true,
    "noUnusedParameters": true,
    "noFallthroughCasesInSwitch": true,
    "strictNullChecks": true,
    "forceConsistentCasingInFileNames": true,
    "noUncheckedIndexedAccess": true,
    "verbatimModuleSyntax": true
  },
  "include": [".astro/types.d.ts", "src/**/*"],
  "exclude": ["dist"]
}
// global.d.ts
import 'astro/astro-jsx';

declare global {
  namespace JSX {
    /* Required by ESLint to work well with Astro. This is fixing elements returned in map loops inside components. */
    // type Element = astroHTML.JSX.Element // We want to use this, but it is defined as any.
    type Element = HTMLElement;
    type IntrinsicElements = astroHTML.JSX.IntrinsicElements;
  }
}
// eslint.config.js
import css from '@eslint/css';
import eslintConfigPrettier from 'eslint-config-prettier/flat';
import { default as astro, default as eslintPluginAstro } from 'eslint-plugin-astro';
import jsxA11y from 'eslint-plugin-jsx-a11y';
import tseslint from 'typescript-eslint';

export default tseslint.config(
  css.configs.recommended,
  tseslint.configs.stylisticTypeChecked,
  tseslint.configs.strictTypeChecked,
  ...eslintPluginAstro.configs.recommended,
  eslintConfigPrettier,
  jsxA11y.flatConfigs.strict,

  astro.configs.recommended,

  {
    languageOptions: {
      // globals: {
      //   ...globals.browser,
      //   ...globals.serviceworker,
      // },
      parserOptions: {
        // TODO There is a bug with the parser: https://github.com/ota-meshi/eslint-plugin-astro/issues/447
        // projectService: {
        //   allowDefaultProject: ['**/*.astro'],
        // },
        // projectService: false,
        project: './tsconfig.eslint.json',
      },
    },
  },

  {
    files: ['*.astro'],
    parser: 'astro-eslint-parser',
    parserOptions: {
      parser: '@typescript-eslint/parser',
      extraFileExtensions: ['.astro'],
    },
  },
);

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

8 participants