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