Skip to content
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

Add rule no-unused-props #1028

Closed
oekazuma opened this issue Jan 15, 2025 · 13 comments · Fixed by #1061 or #1128
Closed

Add rule no-unused-props #1028

oekazuma opened this issue Jan 15, 2025 · 13 comments · Fixed by #1061 or #1128
Labels
enhancement New feature or request new rule

Comments

@oekazuma
Copy link

oekazuma commented Jan 15, 2025

Motivation

This rule aims to ensure consistency between the defined Props type and the actual use of $props().
This prevents mistakes due to overlooking properties and improves code readability and maintainability.
Enforcing this rule helps developers understand and reduces the risk of potential bugs.

Description

Issue a warning if the type of the defined Props does not match the variable destructuring assignment in $props().

Examples

<script lang="ts">
  /* ✓ GOOD */

  interface Props {
    a: string;
    b: number;
  }

  let { a, b }: Props = $props();

  /* ✗ BAD */

  interface Props {
    a: string;
    b: number;
  }

  let { a }: Props = $props();
</script>

Additional comments

No response

@oekazuma oekazuma added enhancement New feature or request new rule labels Jan 15, 2025
@ota-meshi
Copy link
Member

Thank you for proposing the rule!
That rule sounds good to me!

If possible, it would be even better if it could check the usage of unnamed props as well.

<script lang="ts">
	interface Props {
		a: number;
		[key: string]: unknown; // unused
	}

	let {a}: Props = $props();
        // We can guess that the following would be correct:
	// let {a, ...other}: Props = $props();
</script>

And it would be even better if the rule could check member access as well.

<script lang="ts">
  interface Props {
    a: string;
    b: number; // unused
  }

  let props: Props = $props();
</script>

{props.a}
<script lang="ts">
  interface Props {
    a: string;
    b: number;
    c: number; // unused
  }

  let { a, ...otherProps }: Props = $props();
</script>

{otherProps.b}

I think the rule name might be better, something like no-unused-props.
What do you think?

@oekazuma
Copy link
Author

Thanks for the good additional suggestions!

I agree with the rule name, no-unused-props.

@oekazuma oekazuma changed the title Add rule consistent-props-usage Add rule no-unused-props Jan 16, 2025
@shumadrid
Copy link

Did the usual updating of dependencies, ran eslint, got this output produced by this rule, is this intended?:

 27:9  error  'toString' in 'currentDayCommitHash' is an unused property           svelte/no-unused-props
  27:9  error  'charAt' in 'currentDayCommitHash' is an unused property             svelte/no-unused-props
  27:9  error  'charCodeAt' in 'currentDayCommitHash' is an unused property         svelte/no-unused-props
  27:9  error  'concat' in 'currentDayCommitHash' is an unused property             svelte/no-unused-props
  27:9  error  'indexOf' in 'currentDayCommitHash' is an unused property            svelte/no-unused-props
  27:9  error  'lastIndexOf' in 'currentDayCommitHash' is an unused property        svelte/no-unused-props
  27:9  error  'localeCompare' in 'currentDayCommitHash' is an unused property      svelte/no-unused-props
  27:9  error  'match' in 'currentDayCommitHash' is an unused property              svelte/no-unused-props
  27:9  error  'replace' in 'currentDayCommitHash' is an unused property            svelte/no-unused-props
  27:9  error  'search' in 'currentDayCommitHash' is an unused property             svelte/no-unused-props
  27:9  error  'slice' in 'currentDayCommitHash' is an unused property              svelte/no-unused-props
  27:9  error  'split' in 'currentDayCommitHash' is an unused property              svelte/no-unused-props
  27:9  error  'substring' in 'currentDayCommitHash' is an unused property          svelte/no-unused-props
  27:9  error  'toLowerCase' in 'currentDayCommitHash' is an unused property        svelte/no-unused-props
  27:9  error  'toLocaleLowerCase' in 'currentDayCommitHash' is an unused property  svelte/no-unused-props
  27:9  error  'toUpperCase' in 'currentDayCommitHash' is an unused property        svelte/no-unused-props
  27:9  error  'toLocaleUpperCase' in 'currentDayCommitHash' is an unused property  svelte/no-unused-props
  27:9  error  'trim' in 'currentDayCommitHash' is an unused property               svelte/no-unused-props
  27:9  error  'length' in 'currentDayCommitHash' is an unused property             svelte/no-unused-props
  ...

currentDayCommitHash is just a regular string passed as a prop.

@baseballyama
Copy link
Member

baseballyama commented Mar 17, 2025

@shumadrid Can you share us code example?

Like this?

  const { currentDayCommitHash }: { currentDayCommitHash: string } = $props();

@AndersRobstad
Copy link

@baseballyama Here is a minimal repro. It reports object-props as unused even when they have all their attributes referenced. It should probably allow for objects as long as at least one of its attributes is used inside the file

Image

@baseballyama
Copy link
Member

@AndersRobstad Thank you! I will fix this ASAP.

@baseballyama
Copy link
Member

@shumadrid @AndersRobstad We’ve released v3.2.1. Could you please verify if this issue has been resolved? As this rule is relatively complex, there might still be some false positives.

@AndersRobstad
Copy link

@baseballyama We're still seeing this reported as an error, even though the type prop is being referenced.

In our codebase (and I assume many others as well), we often pass objects as props to components instead of just primitive values. This rule feels overly strict in our case since it requires every attribute of an object prop to be explicitly referenced for it to be considered valid.This makes it impractical for files where complex objects are passed as props, as we'd need to reference all of their attributes just to satisfy the rule.

Image

@AndersRobstad
Copy link

AndersRobstad commented Mar 17, 2025

Seems to work fine for classes now though! They correctly only report as unused if they are never referenced at all

@baseballyama
Copy link
Member

@AndersRobstad

By default, the checkImportedTypes option is set to false. This means the rule does not report unused properties for imported types (where the component itself doesn’t own the type definition). On the other hand, types declared within a Svelte component are owned by that component, and thus unused properties should ideally be removable.

Could you please tell me again about the practical issues you’re encountering with your specific use case?

Additionally, we can use the ignorePatterns option to exclude specific patterns. This allows you to balance the rule with practical needs in real-world projects.
https://sveltejs.github.io/eslint-plugin-svelte/rules/no-unused-props/

@AndersRobstad
Copy link

@baseballyama Then the checkImportedTypes option does not seem to work correctly. In the example below the svelte-component imports the TaskViewModel-type, but it still reports errors due to some of its attributes not being used

Image

@baseballyama
Copy link
Member

baseballyama commented Mar 17, 2025

@AndersRobstad Thank you! But this is strange.🤔
I’ll investigate why this is happening.

I've created a issue: #1133

@AndersRobstad
Copy link

AndersRobstad commented Mar 19, 2025

@baseballyama There still seems to be some problems with the reporting of unused props, created a new issue here

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request new rule
Projects
None yet
5 participants