Skip to content

False positive no-unused-props rule when accessing props using a mix of destructuring and property accessors after updating Vite to 5.4.18 #1198

Open
@ChanelZM

Description

@ChanelZM

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.24.0

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

3.5.1

What did you do?

Configuration

import tripleConfig from "eslint-config-triple/svelte";
import svelte from "eslint-plugin-svelte";
import pluginQuery from "@tanstack/eslint-plugin-query";
import svelteConfig from "./svelte.config.js";

export default [
  ...svelte.configs.recommended,
  ...pluginQuery.configs["flat/recommended"],
  ...tripleConfig,
  {
    ignores: [
      "coverage",
      "reports",
      "**/*.config.ts",
      "**/*.config.js",
      "**/tokens.js",
      "build",
      "src/core/services/prepr/generated",
      "src/components/StructuredData/StructuredData.svelte",
      "src/components/DataLayer/DataLayer.svelte",
      "src/routes/theoplayer/[...path]/+server.ts",
    ],
  },
  {
    languageOptions: {
      parserOptions: {
        project: "./tsconfig.json",
      },
    },
  },
  {
    files: ["**/*.svelte", "**/*.svelte.js"],
    languageOptions: {
      parserOptions: {
        svelteConfig,
      },
    },
  },
];

Component

<script lang="ts">
	type Props = {
		disabled?: boolean;
		variant?: 'primary' | 'secondary' | 'persuasive';
		label: string;
		className?: string;
		alignSelf?: 'start' | 'center' | 'end';
		stretch?: boolean;
		maxWidth?: boolean;
	};

	type LinkProps = Props & {
		as: 'link';
		href: string;
		isExternal?: boolean;
		onClick?: () => void;
	};
	type ButtonProps = Props & {
		as: 'button';
		type?: 'button' | 'submit';
		onClick: () => void;
	};

	const props: LinkProps | ButtonProps = $props();
	const { disabled, variant = 'primary', className, alignSelf, stretch, maxWidth, label } = props;
	const classes = [
		'button',
		variant,
		className,
		`align-self-${alignSelf ?? 'start'}`,
		stretch && 'stretch',
		maxWidth && 'max-width'
	];
</script>

{#if props.as === 'link'}
	<a
		href={props.href}
		class={classes}
		aria-disabled={disabled}
		target={props.isExternal ? '_blank' : undefined}
		rel={props.isExternal ? 'noopener noreferrer' : undefined}
		onclick={props.onClick}
	>
		{label}
	</a>
{:else if props.as === 'button'}
	<button
		onclick={() => !disabled && props.onClick()}
		class={classes}
		aria-disabled={disabled}
		type={props.type ?? 'button'}
	>
		{label}
	</button>
{/if}

I've created a minimal reproducible example by running npx sv create my-app which contains Vite 6.2.5 and the problem also arose in that example.

What did you expect to happen?

No error because I am using the destructured props.

What actually happened?

I updated Vite from 5.4.17 to 5.4.18 after a security vulnerability was found in 5.4.17. After updating, I got this message:

[eslint]   31:9  error  'disabled' is an unused Props property   svelte/no-unused-props
[eslint]   31:9  error  'variant' is an unused Props property    svelte/no-unused-props
[eslint]   31:9  error  'label' is an unused Props property      svelte/no-unused-props
[eslint]   31:9  error  'className' is an unused Props property  svelte/no-unused-props
[eslint]   31:9  error  'alignSelf' is an unused Props property  svelte/no-unused-props
[eslint]   31:9  error  'stretch' is an unused Props property    svelte/no-unused-props
[eslint]   31:9  error  'maxWidth' is an unused Props property   svelte/no-unused-props
[eslint]   31:9  error  'icon' is an unused Props property       svelte/no-unused-props

So afterwards I updated eslint-plugin-svelte to 3.5.1 and eslint to 9.24.0 but the problem persisted.
I also tried renaming props to passedProps but with little luck.

Link to GitHub Repo with Minimal Reproducible Example

https://github.com/ChanelZM/eslint-plugin-svelte-minimal-reproducible-example

Additional comments

No response

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions