svelte-eslint-parser
svelte-eslint-parser copied to clipboard
False positive TypeScript ESLint errors when using slot props
Before You File a Bug Report Please Confirm You Have Done The Following...
- [X] I'm using eslint-plugin-svelte. (
*.svelte
file linting does not work with the parser alone. You should also use eslint-plugin-svelte with it.) - [X] I'm sure the problem is a parser problem. (If you are not sure, search for the issue in eslint-plugin-svelte repo and open the issue in eslint-plugin-svelte repo if there is no solution.
- [X] I have tried restarting my IDE and the issue persists.
- [X] I have updated to the latest version of the packages.
What version of ESLint are you using?
8.47.0
What version of eslint-plugin-svelte
and svelte-eslint-parser
are you using?
What did you do?
Configuration
module.exports = { extends: [ 'eslint:recommended', 'plugin:@typescript-eslint/recommended-type-checked', 'plugin:svelte/recommended', ], parser: '@typescript-eslint/parser', plugins: ['@typescript-eslint'], parserOptions: { project: true, tsconfigRootDir: __dirname, extraFileExtensions: ['.svelte'], }, overrides: [ { files: ['*.svelte'], parser: 'svelte-eslint-parser', parserOptions: { parser: '@typescript-eslint/parser', }, }, ], root: true, env: { browser: true, node: true, }, };
// App.svelte
<script lang="ts">
import CustomList from './lib/CustomList.svelte';
import type { ListItem } from './lib/types';
const items: ListItem[] = [
{
title: 'Svelte.dev',
link: 'https://svelte.dev',
},
{
title: 'TypeScript ESLint',
link: 'https://typescript-eslint.io',
},
{
title: 'TypeScript',
link: 'https://www.typescriptlang.org',
},
];
const openLink = (item: ListItem) => {
window.location.replace(item.link);
};
</script>
<main>
<CustomList
{items}
let:item
>
<div>
{item.title}
<button
on:click={() => {
openLink(item);
}}>Open Link</button
>
</div>
</CustomList>
</main>
// CustomList.svelte
<script lang="ts">
import type { ListItem } from './types';
export let items: ListItem[];
</script>
<div>
<ul>
{#each items as item (item.title)}
<li>
<slot {item} />
</li>
{/each}
</ul>
</div>
// types.ts
export interface ListItem {
title: string;
link: string;
}
What did you expect to happen?
No ESLint errors or warnings are raised for the code, as the types are defined and compatible with how they are being used.
What actually happened?
ESLint raises two errors. The first, @typescript-eslint/no-unsafe-member-access
, when accessing the title
property of the item
slot prop; the second, @typescript-eslint/no-unsafe-argument
, passing the item
slot prop to the openLink
function.
Link to GitHub Repo with Minimal Reproducible Example
https://github.com/rowanlovejoy/eslint-svelte-test
Additional comments
The minimal reproduction repo is based on the Vite Svelte template described here: https://vitejs.dev/guide/#scaffolding-your-first-vite-project It includes additional package.json
commands to run ESLint and the TypeScript compiler independently. It uses PNPM.
The template code of the App.svelte
component demonstrates the linting error.
The app renders a list of items. Each item includes a title and a link. For each item, the title is rendered along with a button to open that link in the current browser tab.
I believe this is a parsing problem because this issue occurs only on the template (which I understand the parser transforms into an AST; apologies if this is incorrect, I've never worked on anything like this); the TypeScript compiler correctly understands the code; the errors being raised are not eslint-plugin-svelte
ruleset; and I've used this same configuration in React TypeScript projects with almost identical code and not experienced similar problems.