Before You File a Bug Report Please Confirm You Have Done The Following...
What version of ESLint are you using?
9.19.0
What version of eslint-plugin-svelte and svelte-eslint-parser are you using?
What did you do?
Configuration
// package.json
{
"name": "svelte-snippet-bug",
"private": true,
"version": "0.0.1",
"type": "module",
"scripts": {
"dev": "vite dev",
"build": "vite build",
"preview": "vite preview",
"prepare": "svelte-kit sync || echo ''",
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
"lint": "eslint ."
},
"devDependencies": {
"@eslint/compat": "^1.2.5",
"@eslint/js": "^9.19.0",
"@sveltejs/adapter-auto": "^4.0.0",
"@sveltejs/kit": "^2.16.0",
"@sveltejs/vite-plugin-svelte": "^5.0.3",
"eslint": "^9.19.0",
"eslint-plugin-svelte": "^3.0.0-next.17",
"globals": "^15.14.0",
"svelte": "^5.19.4",
"svelte-check": "^4.1.4",
"typescript": "^5.7.3",
"typescript-eslint": "^8.22.0",
"vite": "^6.0.11"
}
}
// eslint.config.js
import js from '@eslint/js';
import {includeIgnoreFile} from '@eslint/compat';
import svelte from 'eslint-plugin-svelte';
import globals from 'globals';
import {fileURLToPath} from 'node:url';
import ts from 'typescript-eslint';
const gitignorePath = fileURLToPath(new URL("./.gitignore", import.meta.url));
export default ts.config(
includeIgnoreFile(gitignorePath),
js.configs.recommended,
...ts.configs.recommendedTypeChecked,
...svelte.configs["flat/recommended"],
{
ignores: ["**/*.js", 'node_modules/**/*'],
},
{
languageOptions: {
globals: {
...globals.browser,
...globals.node,
},
parserOptions: {
projectService: true,
tsconfigRootDir: import.meta.dirname,
},
},
},
{
files: ["**/*.svelte"],
languageOptions: {
parserOptions: {
parser: ts.parser,
projectService: true,
extraFileExtensions: ['.svelte'],
},
},
}
);
// File ChoiceList.svelte
<script lang="ts" generics="TChoice">
type Props = {
choices: readonly TChoice[];
getKey: (choice: TChoice) => string;
item: import('svelte').Snippet<[{ choice: TChoice }]>,
}
const {choices, getKey, item}: Props = $props();
</script>
<ul>
{#each choices as choice (getKey(choice))}
<li>{@render item({choice})}</li>
{/each}
</ul>
// File +page.svelte
<script lang="ts">
import ChoiceList from "$lib/ChoiceList.svelte";
let choices = [
{id: "1", username: "John Doe"},
{id: "2", username: "Jane Dae"},
]
</script>
<ChoiceList {choices} getKey={(choice) => choice.id}>
{#snippet item({choice})}
{choice.username}
{/snippet}
</ChoiceList>
What did you expect to happen?
There are no errors in this code.
So no errors should be raised when running eslint.
What actually happened?
> [email protected] lint
> eslint .
/svelte-snippet-bug/src/routes/+page.svelte
13:43 error Unsafe return of a value of type `any` @typescript-eslint/no-unsafe-return
13:50 error Unsafe member access .id on an `any` value @typescript-eslint/no-unsafe-member-access
15:17 error Unsafe member access .username on an `any` value @typescript-eslint/no-unsafe-member-access
✖ 3 problems (3 errors, 0 warnings)
Link to GitHub Repo with Minimal Reproducible Example
https://github.com/maarekj/svelte-snippet-bug
Additional comments
I use the tselint.configs.recommendedTypeChecked instead of just tseslint.configs.recommended
https://typescript-eslint.io/getting-started/typed-linting
Before You File a Bug Report Please Confirm You Have Done The Following...
*.sveltefile linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.)What version of ESLint are you using?
9.19.0
What version of
eslint-plugin-svelteandsvelte-eslint-parserare you using?What did you do?
Configuration
What did you expect to happen?
There are no errors in this code.
So no errors should be raised when running eslint.
What actually happened?
Link to GitHub Repo with Minimal Reproducible Example
https://github.com/maarekj/svelte-snippet-bug
Additional comments
I use the
tselint.configs.recommendedTypeCheckedinstead of justtseslint.configs.recommendedhttps://typescript-eslint.io/getting-started/typed-linting