Skip to content

Union types for props cause trigger of svelte/no-unused-props #1168

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

Closed
2 tasks done
WarningImHack3r opened this issue Mar 30, 2025 · 5 comments · Fixed by #1171
Closed
2 tasks done

Union types for props cause trigger of svelte/no-unused-props #1168

WarningImHack3r opened this issue Mar 30, 2025 · 5 comments · Fixed by #1171

Comments

@WarningImHack3r
Copy link

WarningImHack3r commented Mar 30, 2025

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

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

3.4.0

What did you do?

Configuration
import eslint from "@eslint/js";
import tseslint from "typescript-eslint";
import svelte from "eslint-plugin-svelte";
import prettierConfig from "eslint-config-prettier/flat";
import globals from "globals";
import svelteConfig from "./svelte.config.js";

export default tseslint.config(
	eslint.configs.recommended,
	tseslint.configs.recommended,
	svelte.configs.recommended,
	prettierConfig,
	svelte.configs.prettier,
	{
		languageOptions: {
			globals: {
				...globals.browser,
				...globals.node
			}
		}
	},
	{
		files: ["**/*.svelte", "**/*.svelte.js", "**/*.svelte.ts"],
		languageOptions: {
			parserOptions: {
				parser: tseslint.parser,
				extraFileExtensions: [".svelte"],
				projectService: true,
				svelteConfig
			}
		}
	},
	{
		rules: {
			"@typescript-eslint/no-unused-vars": ["error", { ignoreRestSiblings: true }]
		}
	},
	{
		ignores: ["build/", ".svelte-kit/", "dist/", "src/lib/components/ui/", "src/lib/utils.[jt]s"]
	}
);
<script lang="ts">
	type MyType = { thing: string };
	type Props = {
		myProp: { a: string } & MyType;
	};
	let { myProp }: Props = $props();
</script>

{myProp.thing}

If I don't use myProp.a in my code, even if I use one or more properties of MyType, a is marked as unused props

What did you expect to happen?

Not having this reported because I do use myProp

What actually happened?

Got this error reported on my $props()

Link to GitHub Repo with Minimal Reproducible Example

https://eslint-online-playground.netlify.app/#eNqFVE1v2zAM/SuCMAxdENv3rB0KdNut2LDtVuXg2IynVJYMSU4TBP7vpT7sOHGSnmSTj+R7FMUDNbrInvdPqm6UBGlTswVhgS7ovSk0bywRuaweGLWG0W9MMmv3DZDn/T93PJADsf+5rBbEWI0n6b4OmN9aNcZBnIXZeu8MC4zIj2jyOabyYSFYgEVQgJNuMeT51LiPuy8Ius8COUdIHgI09UQ6JumcghEctRRKrnmVbgzK4ShQWxI8ZK1VTRh9DL/ZBsVh2oix5hTl1IR6SXCMwaFfPTT4k0a0FZdJ8I3RjQZrOegnz+wsKtBNeky2FvlJqUqoVS5MHxV/PYJJ2HlMCeu8FUcNsQd3rrEnFpNqKFRdgyyhnPtLOw2ZAoKcq+5TbZcieoT3xbFw49XmFfxqLFfS4HwEO7NR38jCbJqm0ZyutHozMdfEKVUJvQNHYji6cek1F4DpXxidzbJZnHxG59jbkQHHZ2pzr2EZS19X0OQaGU7tvWdxvKZgGImBndX5T2T4Y2dBmpABqQ40lx/q063XdyxLHyejnEmVtLI1UCZbpMCoLwJaK+1UHwivpNLwB4z9y1cYUWFGzAykiwSmdUNIoLtquSiz0MBIPXnlNlpKbvpPt4cEX2U4U2ETmazlZ77Wcrzbl41duvb7uky6fYBPvsmLV7wEvC0l8bkjFRKfrtPEaK1KbAfmC44Stt+hccMrCw5etw9xvvFWcKH4DFF+DHWAfgvccJ4/5tvgs31xETo894vem6Gx730xP2pXoMcB+RAwLMMxzsHwUtwa7t4BzLVIRw== (can't make typescript work)

Additional comments

No response

@baseballyama
Copy link
Member

This is the expected behavior. a is defined within this Svelte component, which means the component has ownership of it. Since a is unused, it can be safely removed.
I’ll close this issue for now, but if this behavior causes an actual problem in a real project, please let me know the details. I’ll reopen the issue and consider what can be done.

@WarningImHack3r
Copy link
Author

I can see why it's like this, but it's a bit of an out-of-scope decision in my opinion. Technically, my prop is used, but not all of its properties. This means that we have to separately define types to avoid this behavior, which seems a bit intrusive for a simple lint rule.
I could remove a, but it leads to a "TypeScript lie" because the object I pass in has more properties than what I define in my component.

Also, if I disable this in this component/altogether, I lose the cases when I actually have an unused prop, which is annoying.

The possibilities are the following:

  • Creating a separate rule svelte/no-unused-props-member or something that's a warning for this specific case
  • Add a configuration for this rule to lower the level/disable the case of my issue (<- Preferred case)
  • Remove that case from this rule altogether
  • Change the report location of this issue to the type or the precise prop, not in the let { ... location
  • Disable this rule in the concerned components, which makes me lose potential actually unused props
  • Disable this rule globally, which is straight up bad
  • Lower the level of this rule, which is still blocking with a regular ESLint run

By the way, if the issue stays in this state, it should be closed as "Won't solve" and not as "Completed"

@baseballyama
Copy link
Member

baseballyama commented Mar 31, 2025

Let's add allowUnusedNestedProperties option. (Default is false)

@WarningImHack3r
Copy link
Author

Great thank you!!

@baseballyama
Copy link
Member

This issue is fixed in v3.5.0

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

Successfully merging a pull request may close this issue.

2 participants