-
-
Notifications
You must be signed in to change notification settings - Fork 42
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
Linting with flat config (ESLint 9) does not work with TypeScript #732
Comments
Hey, I had it working with the following config: import js from "@eslint/js";
import eslintConfigPrettier from "eslint-config-prettier";
import eslintPluginSvelte from "eslint-plugin-svelte";
import globals from "globals";
import svelteParser from "svelte-eslint-parser";
import tsEslint from "typescript-eslint";
export default tsEslint.config(
js.configs.recommended,
...tsEslint.configs.recommended,
...eslintPluginSvelte.configs["flat/recommended"],
eslintConfigPrettier,
...eslintPluginSvelte.configs["flat/prettier"],
{
languageOptions: {
ecmaVersion: 2022,
sourceType: "module",
globals: { ...globals.node, ...globals.browser },
parser: svelteParser,
parserOptions: {
parser: tsEslint.parser,
extraFileExtensions: [".svelte"],
},
},
},
{
ignores: [
"**/.svelte-kit",
"**/.vercel",
"**/.yarn",
"**/build",
"**/node_modules",
"**/package",
],
},
); Hope it helps Edit: updated with better imports and ignores |
Also working for me. According to the rollout tracker there is support.
|
Thank you for helping out, i really appreciate it! This config works for my Svelte files it seems like, but in almost all my TypeScript files i get a |
Thank you for helping out, i appreciate it! This config works fine for me on TypeScript files, but it does not work on Svelte files. The funny thing is that i tried to merge your and @GauBen's configs (because the one works with TS and the other with Svelte), but with no luck. :/ |
@MathiasWP : I had the same problem as you, but I got it working by adding My understanding, is that by adding {
files: ["**/*.svelte"],
languageOptions: {
ecmaVersion: 2022,
sourceType: "module",
parser: svelteParser,
parserOptions: {
parser: tsParser,
extraFileExtensions: [".svelte"],
},
},
}, I am not sure what the |
Thank you so much! This solved the issue for me! 🎉 |
For completeness, here is a full Maybe an example of such a "flat file" config could be added to the doc of // eslint.config.cjs
import eslintPluginPrettierRecommended from 'eslint-plugin-prettier/recommended';
import eslintPluginSvelte from 'eslint-plugin-svelte';
import js from '@eslint/js';
import svelteParser from 'svelte-eslint-parser';
import tsEslint from 'typescript-eslint';
import tsParser from '@typescript-eslint/parser';
export default [
js.configs.recommended,
...tsEslint.configs.strict,
...eslintPluginSvelte.configs['flat/recommended'],
eslintPluginPrettierRecommended, // must be last to override conflicting rules.
{
rules: {
semi: ['warn', 'always'],
quotes: [
'warn',
'single',
{ avoidEscape: true, allowTemplateLiterals: true },
],
'no-nested-ternary': 'error',
'linebreak-style': ['error', 'unix'],
'no-cond-assign': ['error', 'always'],
'no-console': 'error',
'@typescript-eslint/sort-type-constituents': 'error',
'sort-imports': [
'error',
{
ignoreCase: true,
ignoreDeclarationSort: false,
ignoreMemberSort: false,
memberSyntaxSortOrder: ['none', 'all', 'multiple', 'single'],
allowSeparatedGroups: true,
},
],
},
},
{
files: ['**/*.svelte'],
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: tsParser,
},
},
rules: {
'svelte/no-target-blank': 'error',
'svelte/no-at-debug-tags': 'error',
'svelte/no-reactive-functions': 'error',
'svelte/no-reactive-literals': 'error',
},
},
]; |
I found why my config file was not working with ts files in vscode, yet the command line interface worked as expected! I needed this config line in vscode: |
I agree, having an example would help a lot |
This should be added to the readme in the parser configuration section. We also don't have to import the ts parser see here https://typescript-eslint.io/packages/typescript-eslint/#manually-configuring-our-plugin-and-parser. |
Thanks, feels nice to remove |
I managed to lint both TypeScript import eslint from "@eslint/js";
import pluginImport from "eslint-plugin-import";
import svelteEslint from "eslint-plugin-svelte";
import globals from "globals";
import svelteParser from "svelte-eslint-parser";
import tsEslint from "typescript-eslint";
export default [
eslint.configs.recommended,
...tsEslint.configs.recommended,
...svelteEslint.configs["flat/recommended"],
{
files: ["**/*.svelte"],
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: tsEslint.parser
},
globals: {
...globals.browser
}
}
},
{
files: ["**/*.ts"],
languageOptions: {
parser: tsEslint.parser
}
},
{
plugins: {
"@typescript-eslint": tsEslint.plugin,
import: pluginImport
},
rules: {
semi: "warn",
"svelte/sort-attributes": "warn"
}
}
]; |
Thanks for all the config hints - I'm new to svelte and eslint 9 is complaining with this config about eslint.config.cjs
Running it with |
@szinn Change the filename to |
Ah, I also reinstalled modules - prettier config caused grief as well |
This is wonderful! I was able to use and extend the above into a config that supports custom configs for my test files, with the addition of the markdown linter, and the jsdoc linter. Hopefully this helps others build even better ones! See my
|
@robinengler I wanted to answer this Q because it's important to understand why thigns are done! The ts parser will ignore files with file extensions it doesn't expect (such as
If you weren't getting any errors from removing this line, it could be that your config was not actually linting the |
I think that it helps you to specify import globals from 'globals';
import js from '@eslint/js';
import tseslint from 'typescript-eslint' // v7
import prettierConfig from 'eslint-config-prettier';
import svelte from 'eslint-plugin-svelte';
import svelteParser from 'svelte-eslint-parser';
/** @type {import('typescript-eslint').Config} */
export default = [
...[
js.configs.recommended,
...tseslint.configs.strictTypeChecked, // typescript-eslint set `['**/*.ts', '**/*.tsx', '**/*.mts', '**/*.cts']` to `files`
prettierConfig, // eslint-config-prettier does not turn 'svelte/*' rules off
{ // overrides options should be after other config
languageOptions: {
parser: tseslint.parser,
parserOptions: {
sourceType: 'module',
extraFileExtensions: ['.svelte']
},
globals: { ...globals.browser, ...globals.node },
},
rules: { /* rules for js/ts/svelte */ } // don't set 'svelte/*' rules here
}
].map(conf => ({ ...conf, files: ['**/*.js', '**/*.ts', '**/*.svelte'] })), // To override `files` is so important!!
...svelte.configs['flat/recommended'], // eslint-plugin-svelte set `['*.svelte', '**/*.svelte']` to `files`
...svelte.configs['flat/prettier'], // if non svelte files occur 'svelte/*' error, these element should be set `files`
{ // your config should be after
files: ['*.svelte', '**/*.svelte'], // the same value as eslint-plugin-svelte `files` option
languageOptions: {
parser: svelteParser,
parserOptions: { parser: tseslint.parser }
},
// ↓ rule types; sveltejs/eslint-plugin-svelte #735
/** @type {import('eslint').Linter.RulesRecord} */
rules: { /* rules for svelte */ }
},
{
// other override settings. e.g. for `files: ['**/*.test.*']`
},
{ ignores: ['node_modules/', /* other ignores */] } // overrides global ignores
]; It because that Note
Using typescript-eslint helper function eslint.config.js using `config` helperimport globals from 'globals';
import js from '@eslint/js';
import tseslint from 'typescript-eslint' // v7
import prettierConfig from 'eslint-config-prettier';
import svelte from 'eslint-plugin-svelte';
import svelteParser from 'svelte-eslint-parser';
const defaultConfig = tseslint.config({
files: ['**/*.js', '**/*.ts', '**/*.svelte'],
extends: [
js.configs.recommended, // if it occurs a type error, you can install `@types/eslint__js` package
...tseslint.configs.strictTypeChecked,
prettierConfig // if it occurs a type error, you can install `@types/eslint-config-prettier` package
],
languageOptions: {
parser: tseslint.parser,
parserOptions: {
sourceType: 'module',
extraFileExtensions: ['.svelte']
},
globals: { ...globals.browser, ...globals.node },
},
rules: { /* rules for js/ts/svelte */ } // don't set 'svelte/*' rules here
});
const svelteConfig = tseslint.config({
extends: [
...svelte.configs['flat/recommended'],
...svelte.configs['flat/prettier']
],
languageOptions: {
parser: svelteParser,
parserOptions: { parser: tseslint.parser }
},
// ↓ rule types; sveltejs/eslint-plugin-svelte #735
/** @type {import('eslint').Linter.RulesRecord} */
rules: { /* rules for svelte */ }
});
/** @type {import('@typescript-eslint/utils').TSESLint.FlatConfig.ConfigArray} */
export default = [
...defaultConfig,
...svelteConfig,
{
// other override settings. e.g. for `files: ['**/*.test.*']`
},
{ ignores: ['node_modules/', /* other ignores */] } // overrides global ignores
]; |
I haven't been able to get any of the above configs working with eslint 9.3.0 and typescript-eslint 8.0.0-alpha.20 for .svelte files but it does work for all .js and .ts files. From typescript-eslint/typescript-eslint#8211:
The error I'm seeing on .svelte files is: Here is an example config that is getting this error. eslint.config.jsimport js from '@eslint/js';
import ts from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
const tsConfig = ts.config({
files: ['**/*.js', '**/*.ts', '**/*.svelte'],
extends: [
js.configs.recommended,
...ts.configs.strictTypeChecked,
...ts.configs.stylisticTypeChecked,
prettier
],
languageOptions: {
globals: {
...globals.browser,
...globals.nodeBuiltin
},
parserOptions: {
project: './tsconfig.eslint.json',
tsconfigRootDir: import.meta.dirname,
extraFileExtensions: ['.svelte']
}
}
});
const svelteConfig = ts.config({
files: ['**/*.svelte'],
extends: [...svelte.configs['flat/recommended'], ...svelte.configs['flat/prettier']],
languageOptions: {
parserOptions: {
parser: ts.parser
}
}
});
export default ts.config(...tsConfig, ...svelteConfig, {
ignores: ['.svelte-kit/']
}); tsconfig.eslint.json{
"extends": "./tsconfig.json",
"files": ["eslint.config.js", "svelte.config.js", "vite.config.ts"]
} tsconfig.json{
"extends": "./.svelte-kit/tsconfig.json",
"compilerOptions": {
"allowJs": true,
"checkJs": true,
"esModuleInterop": true,
"forceConsistentCasingInFileNames": true,
"resolveJsonModule": true,
"skipLibCheck": true,
"sourceMap": true,
"strict": true,
"moduleResolution": "bundler"
}
} |
Thanks for this! I was wondering if we could see the |
Did you look at the one I posted above (hidden in a The primary difference I see is I am not using the pre-release alpha, but the stable release:
|
Here is the relevant section of my
|
When I try to install this package via
I run into a similar error when trying to install typescript-eslint via
My understanding is both these packages (
|
Thanks for all your comments! I still don't know the best practices for integrating with typescript-eslint, but using typescript-eslint@v8-beta might work. |
While the provided configs work for the simple recommended ruleset I cannot get it to work with the actual type-checking configs of typescript-eslint. To enable actual type-parsing, we need to enable the Parsing error: "parserOptions.programs" has been provided for @typescript-eslint/parser. import epSvelte from 'eslint-plugin-svelte'
import svelteParser from 'svelte-eslint-parser'
import tsEslint from 'typescript-eslint'
export default [
...tsEslint.configs.strictTypeChecked,
...epSvelte.configs['flat/recommended'],
{
languageOptions: {
parser: tsEslint.parser,
parserOptions: {
project: true, // This line breaks the config (even with the other configs) - but it is needed for type-checking.
},
},
},
{
files: ['**/*.svelte'],
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: tsEslint.parser,
}
},
},
] And the inclusion of extra-file extensions doesn't make a difference. Also including the project: true in both parserOptions doesn't change anything. JS/TS Files get handled correctly, but svelte files are not recognized as soon as "project" is set to anything. |
@kkirkfield It seems to work when I add |
https://typescript-eslint.io/packages/parser#programs To clarify some of the other confusion above... project and tsconfigRootDirIf you want to use the strict type checked rules from typescript-eslint then you need to set extraFileExtensionsFor this setting you need to include the Here is a link to an issue showing how this is working as intended. typescript-eslint v7There is no plan to officially backport support for eslint v9 to typescript-eslint v7. Support for eslint v9 is only officially supported in typescript-eslint v8 beta. I linked to this above in an early comment but I'm including it here as well. From typescript-eslint/typescript-eslint#8211:
|
|
I could get it working initially and I didn't even know it was an issue for someone. Below is my config (yeah I know it's messy, lmk if I can make it better) eslint.config.js
I guess the main reason I could get something working with strict type checking rules (@falco467 case) because I was using @ota-meshi typescript-eslint-parser-for-extra-files But today I stumbled upon strange case which I've never seen before:
I am using all latest packages (literally, upgraded all just right before posting). typescript-eslint@8.0.0-alpha.29 @ota-meshi you got any ideas? could this be an issue for extra files parser? upd: for a workaround i am currently using empty string instead of undefined: |
@falco467 eslint.config.jsimport js from '@eslint/js';
import ts from 'typescript-eslint';
import prettier from 'eslint-config-prettier';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
const tsConfig = ts.config({
files: ['**/*.js', '**/*.ts', '**/*.svelte'],
extends: [
js.configs.recommended,
...ts.configs.strictTypeChecked,
...ts.configs.stylisticTypeChecked,
prettier
],
languageOptions: {
globals: {
...globals.browser,
...globals.nodeBuiltin
},
parserOptions: {
project: './tsconfig.eslint.json',
tsconfigRootDir: import.meta.dirname,
extraFileExtensions: ['.svelte'],
programs: false
}
}
});
const svelteConfig = ts.config({
files: ['**/*.svelte'],
extends: [...svelte.configs['flat/recommended'], ...svelte.configs['flat/prettier']],
languageOptions: {
parserOptions: {
parser: ts.parser
}
}
});
export default ts.config(...tsConfig, ...svelteConfig, {
ignores: ['.svelte-kit/']
}); |
This seems to be working nicely for me along with type safety inside eslint.config.js
// @ts-check
import js from '@eslint/js';
import playwright from 'eslint-plugin-playwright';
import prettier from 'eslint-plugin-prettier/recommended';
import svelte from 'eslint-plugin-svelte';
import vitest from 'eslint-plugin-vitest';
import globals from 'globals';
import svelteParser from 'svelte-eslint-parser';
import ts from 'typescript-eslint';
/** @type {import('typescript-eslint').Config} */
export default ts.config(
js.configs.recommended,
...ts.configs.recommendedTypeChecked,
...svelte.configs['flat/recommended'],
prettier,
...svelte.configs['flat/prettier'],
{
...playwright.configs['flat/recommended'],
files: ['tests/**'], // or any other pattern
plugins: {
vitest
},
rules: {
...vitest.configs.recommended.rules
},
settings: {
vitest: {
typecheck: true
}
},
languageOptions: {
globals: {
...vitest.environments.env.globals
}
}
},
{
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: { ...globals.node, ...globals.browser },
parserOptions: {
project: true,
parser: ts.parser,
extraFileExtensions: ['.svelte'],
tsconfigRootDir: import.meta.dirname
}
}
},
{
files: ['**/*.svelte', '*.svelte'],
languageOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
globals: { ...globals.browser },
parser: svelteParser,
parserOptions: {
parser: ts.parser,
extraFileExtensions: ['.svelte']
}
},
rules: {
'import/no-named-as-default': 'off',
'import/no-named-as-default-member': 'off',
'svelte/no-target-blank': 'error',
'svelte/no-at-debug-tags': 'error',
'svelte/no-reactive-functions': 'error',
'svelte/no-reactive-literals': 'error'
}
},
{
rules: {
semi: ['warn', 'always'],
quotes: ['warn', 'single', { avoidEscape: true, allowTemplateLiterals: true }],
'no-nested-ternary': 'error',
'linebreak-style': ['error', 'unix'],
'no-cond-assign': ['error', 'always'],
'@typescript-eslint/sort-type-constituents': 'error',
'no-console': ['error', { allow: ['warn', 'error'] }]
}
},
{
files: ['**/*.config.*'],
extends: [ts.configs.disableTypeChecked]
},
{
ignores: [
'coverage',
'**/dist',
'**/build',
'**/.husky',
'**/package',
'**/.svelte-kit',
'**/docker-data',
'**/node_modules',
'src/lib/i18n/*.ts',
'.env',
'.env.*',
'!*.cjs',
'yarn.lock',
'.DS_Store',
'!.env.example',
'pnpm-lock.yaml',
'package-lock.json'
]
}
); I am waiting for drizzle to publish eslint v9 supported plugin to use that also as that is one of the tools i use most. And it's always helpful to have a red squiggles preventing you from writing bad queries. |
Something to note that I haven't see mentioned yet, parserOptions: {
- project: true,
+ projectService: true,
|
Wouldn't have managed to do it without the examples found in sveltejs/eslint-plugin-svelte#732
That's what works for me: "@eslint/js": "^9.8.0",
"typescript-eslint": "^8.0.0",
"eslint-plugin-svelte": "^2.43.0", import js from "@eslint/js";
import ts from "typescript-eslint";
import svelte from "eslint-plugin-svelte";
import svelte_config from "./svelte.config.js";
/** @type {import("eslint").Linter.Config[]} */
export default [
// js
js.configs.recommended,
// ts
...ts.configs.recommendedTypeChecked,
...ts.configs.strictTypeChecked,
...ts.configs.stylisticTypeChecked,
// ts config
{
rules: {
// ...
},
},
{
languageOptions: {
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
// other plugins
// ...
// svelte
...svelte.configs["flat/recommended"],
// svelte config
{
rules: {
// ...
},
},
{
files: ["**/*.svelte"],
languageOptions: {
parserOptions: {
extraFileExtensions: [".svelte"],
parser: ts.parser,
svelteConfig: svelte_config,
},
},
},
// prettier
prettier
...svelte.configs["flat/prettier"],
// other
{
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
},
ignores: ["build/", ".svelte-kit/"],
},
]; |
This worked for me. I have a monorepo using import stylisticEslint from '@stylistic/eslint-plugin';
import sveltePlugin from 'eslint-plugin-svelte';
import globals from "globals";
import svelteParser from "svelte-eslint-parser";
import tsEslint, { config, configs as tsConfigs } from 'typescript-eslint';
import svelteConfig from "./frontend/svelte.config.js";
export default config(
...tsConfigs.strictTypeChecked,
...tsConfigs.stylisticTypeChecked,
stylisticEslint.configs['recommended-flat'],
{
name: "stylistic",
plugins: {
'@stylistic': stylisticEslint,
},
languageOptions: {
parser: tsEslint.parser,
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
rules: {
'@typescript-eslint/no-require-imports': ['off'],
"@typescript-eslint/restrict-template-expressions": ['off'],
},
},
...sveltePlugin.configs["flat/recommended"],
{
name: "svelte",
files: ["**/*.svelte"],
plugins: {
'svelte': sveltePlugin,
},
languageOptions: {
parser: svelteParser,
parserOptions: {
parser: tsEslint.parser,
extraFileExtensions: [".svelte"],
svelteConfig: svelteConfig,
},
}
},
{
name: 'globals',
languageOptions: {
globals: {
...globals.browser,
...globals.node,
}
}
},
{
name: 'ignores',
ignores: ["**/build", "**/.svelte-kit", "**/dist", "**/*.config.js", "**/*.config.ts", "**/wallaby.js"]
}
) and my {
"eslint.format.enable": true,
"editor.formatOnSave": true,
"eslint.validate": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"svelte"
],
"[javascript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[typescript]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
},
"[svelte]": {
"editor.defaultFormatter": "dbaeumer.vscode-eslint"
}
} |
I got the error
My config file import tseslint from '@typescript-eslint/eslint-plugin';
import eslintParser from "@typescript-eslint/parser"
import js from "@eslint/js";
import love from 'eslint-config-love'
import globals from 'globals'
export default [
js.configs.recommended,
{
languageOptions: {
parser: eslintParser,
parserOptions: {
ecmaVersion: 'latest',
sourceType: 'module',
tsconfigRootDir: import.meta.dirname,
projectService: true,
},
projectService: {
allowDefaultProject: ['*.js'],
defaultProject: true,
},
globals: { ...globals.browser, ...globals.node }
}
},
{
...love,
files: ['**/*.js', '**/*.ts'],
},
{
plugins: {
"@typescript-eslint": tseslint
},
rules: {
'@typescript-eslint/prefer-nullish-coalescing': 'off',
'no-mixed-operators': 'off',
'@typescript-eslint/no-misused-promises': 'off',
'@typescript-eslint/strict-boolean-expressions': 'off',
'@typescript-eslint/no-magic-numbers': 'off',
'complexity': 'off',
'guard-for-in': 'off',
'@typescript-eslint/no-unnecessary-condition': 'off',
'@typescript-eslint/init-declarations': 'off',
"semi": "off",
'no-console': 'off',
'eqeqeq': 'error',
'eslint-comments/require-description': 'off',
'@typescript-eslint/no-unsafe-assignment': 'off',
'@typescript-eslint/no-unsafe-member-access': 'off',
}
},
{
ignores: ["**/dist/","**/temp/","**/cache/",]
}
] |
We can create a project with ESLint preconfigured by running |
Before You File a Bug Report Please Confirm You Have Done The Following...
What version of ESLint are you using?
9.0.0
What version of
eslint-plugin-svelte
are you using?2.36.0
What did you do?
Configuration
What did you expect to happen?
The linter to be happy
What actually happened?
Link to GitHub Repo with Minimal Reproducible Example
https://github.com/MathiasWP/eslint-9-svelte-typescript-error
Additional comments
No response
The text was updated successfully, but these errors were encountered: