From 45cb3e6f3e5f02abf976350dedc70cc857b1d162 Mon Sep 17 00:00:00 2001 From: baseballyama Date: Tue, 18 Mar 2025 19:17:11 +0900 Subject: [PATCH] fix: stop reporting child properties in `no-unused-props` when the parent object is used --- .changeset/floppy-symbols-sing.md | 5 +++ .../src/rules/no-unused-props.ts | 38 +++++++++++++++---- .../valid/nested-props2-input.svelte | 14 +++++++ .../valid/nested-props3-input.svelte | 16 ++++++++ .../valid/nested-props4-input.svelte | 17 +++++++++ 5 files changed, 83 insertions(+), 7 deletions(-) create mode 100644 .changeset/floppy-symbols-sing.md create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props2-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props3-input.svelte create mode 100644 packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props4-input.svelte diff --git a/.changeset/floppy-symbols-sing.md b/.changeset/floppy-symbols-sing.md new file mode 100644 index 000000000..11aa7c646 --- /dev/null +++ b/.changeset/floppy-symbols-sing.md @@ -0,0 +1,5 @@ +--- +'eslint-plugin-svelte': patch +--- + +fix: stop reporting child properties in `no-unused-props` when the parent object itself is used diff --git a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts index 84faa365e..5de3133c0 100644 --- a/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts +++ b/packages/eslint-plugin-svelte/src/rules/no-unused-props.ts @@ -156,7 +156,12 @@ export default createRule('no-unused-props', { const paths: PropertyPath[] = []; for (const reference of variable.references) { - if ('identifier' in reference && reference.identifier.type === 'Identifier') { + if ( + 'identifier' in reference && + reference.identifier.type === 'Identifier' && + (reference.identifier.range[0] !== node.range[0] || + reference.identifier.range[1] !== node.range[1]) + ) { const referencePath = getPropertyPath(reference.identifier); paths.push(referencePath); } @@ -265,11 +270,17 @@ export default createRule('no-unused-props', { if (reportedProps.has(currentPathStr)) continue; const propType = typeChecker.getTypeOfSymbol(prop); - const isUsedInPath = usedPaths.some((path) => { - const usedPath = path.join('.'); - return usedPath === currentPathStr || usedPath.startsWith(`${currentPathStr}.`); + + const joinedUsedPaths = usedPaths.map((path) => path.join('.')); + const isUsedThisInPath = joinedUsedPaths.includes(currentPathStr); + const isUsedInPath = joinedUsedPaths.some((path) => { + return path.startsWith(`${currentPathStr}.`); }); + if (isUsedThisInPath && !isUsedInPath) { + continue; + } + const isUsedInProps = usedProps.has(propName); if (!isUsedInPath && !isUsedInProps) { @@ -282,10 +293,11 @@ export default createRule('no-unused-props', { parent: parentPath.join('.') } }); + continue; } - const isUsedNested = usedPaths.some((path) => { - return path.join('.').startsWith(`${currentPathStr}.`); + const isUsedNested = joinedUsedPaths.some((path) => { + return path.startsWith(`${currentPathStr}.`); }); if (isUsedNested || isUsedInProps) { @@ -324,6 +336,18 @@ export default createRule('no-unused-props', { return usedProps.size === 0; } + function normalizeUsedPaths(paths: PropertyPath[]): PropertyPath[] { + const normalized: PropertyPath[] = []; + for (const path of paths.sort((a, b) => a.length - b.length)) { + if (path.length === 0) continue; + if (normalized.some((p) => p.every((part, idx) => part === path[idx]))) { + continue; + } + normalized.push(path); + } + return normalized; + } + return { 'VariableDeclaration > VariableDeclarator': (node: TSESTree.VariableDeclarator) => { // Only check $props declarations @@ -359,7 +383,7 @@ export default createRule('no-unused-props', { checkUnusedProperties( propType, - usedPaths, + normalizeUsedPaths(usedPaths), usedProps, node.id, [], diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props2-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props2-input.svelte new file mode 100644 index 000000000..3fb8790fd --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props2-input.svelte @@ -0,0 +1,14 @@ + + +Test diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props3-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props3-input.svelte new file mode 100644 index 000000000..7090054f8 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props3-input.svelte @@ -0,0 +1,16 @@ + + +Test diff --git a/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props4-input.svelte b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props4-input.svelte new file mode 100644 index 000000000..15bdb1277 --- /dev/null +++ b/packages/eslint-plugin-svelte/tests/fixtures/rules/no-unused-props/valid/nested-props4-input.svelte @@ -0,0 +1,17 @@ + + +Test +Test