Skip to content

Commit 7892f4c

Browse files
authored
fix(no-unused-props): handle alias props name properly (#1178)
1 parent 469bedf commit 7892f4c

File tree

5 files changed

+53
-9
lines changed

5 files changed

+53
-9
lines changed

Diff for: .changeset/fifty-jeans-thank.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
'eslint-plugin-svelte': patch
3+
---
4+
5+
fix(no-unused-props): handle alias props name properly

Diff for: packages/eslint-plugin-svelte/src/rules/no-unused-props.ts

+23-9
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { findVariable } from '../utils/ast-utils.js';
66
import { toRegExp } from '../utils/regexp.js';
77

88
type PropertyPathArray = string[];
9+
type DeclaredPropertyNames = Set<{ originalName: string; aliasName: string }>;
910

1011
let isRemovedWarningShown = false;
1112

@@ -182,16 +183,27 @@ export default createRule('no-unused-props', {
182183
return sourceFile.fileName.includes('node_modules/typescript/lib/');
183184
}
184185

185-
function getUsedPropertyNamesFromPattern(pattern: TSESTree.ObjectPattern): Set<string> {
186-
const usedProps = new Set<string>();
186+
function getUsedPropertyNamesFromPattern(
187+
pattern: TSESTree.ObjectPattern
188+
): DeclaredPropertyNames {
189+
const usedProps: DeclaredPropertyNames = new Set();
187190
for (const prop of pattern.properties) {
188-
if (prop.type === 'Property' && prop.key.type === 'Identifier') {
189-
usedProps.add(prop.key.name);
191+
if (prop.type === 'Property') {
192+
if (prop.key.type === 'Identifier') {
193+
usedProps.add({ originalName: prop.key.name, aliasName: prop.key.name });
194+
} else if (
195+
prop.key.type === 'Literal' &&
196+
typeof prop.key.value === 'string' &&
197+
prop.value.type === 'Identifier'
198+
) {
199+
usedProps.add({ originalName: prop.key.value, aliasName: prop.value.name });
200+
}
190201
} else if (prop.type === 'RestElement') {
191202
// If there's a rest element, all properties are potentially used
192203
return new Set();
193204
}
194205
}
206+
195207
return usedProps;
196208
}
197209

@@ -229,7 +241,7 @@ export default createRule('no-unused-props', {
229241
}: {
230242
propsType: ts.Type;
231243
usedPropertyPaths: string[];
232-
declaredPropertyNames: Set<string>;
244+
declaredPropertyNames: DeclaredPropertyNames;
233245
reportNode: TSESTree.Node;
234246
parentPath: string[];
235247
checkedPropsTypes: Set<string>;
@@ -287,7 +299,9 @@ export default createRule('no-unused-props', {
287299
continue;
288300
}
289301

290-
const isUsedInProps = declaredPropertyNames.has(propName);
302+
const isUsedInProps = Array.from(declaredPropertyNames).some((p) => {
303+
return p.originalName === propName;
304+
});
291305

292306
if (!isUsedInPath && !isUsedInProps) {
293307
reportedPropertyPaths.add(currentPathStr);
@@ -338,8 +352,8 @@ export default createRule('no-unused-props', {
338352
* Returns true if the destructuring pattern includes a rest element,
339353
* which means all remaining properties are potentially used.
340354
*/
341-
function hasRestElement(usedProps: Set<string>): boolean {
342-
return usedProps.size === 0;
355+
function hasRestElement(declaredPropertyNames: DeclaredPropertyNames): boolean {
356+
return declaredPropertyNames.size === 0;
343357
}
344358

345359
function normalizeUsedPaths(paths: PropertyPathArray[]): PropertyPathArray[] {
@@ -370,7 +384,7 @@ export default createRule('no-unused-props', {
370384

371385
const propsType = typeChecker.getTypeFromTypeNode(tsNode.type);
372386
let usedPropertyPathsArray: PropertyPathArray[] = [];
373-
let declaredPropertyNames = new Set<string>();
387+
let declaredPropertyNames: DeclaredPropertyNames = new Set();
374388

375389
if (node.id.type === 'ObjectPattern') {
376390
declaredPropertyNames = getUsedPropertyNamesFromPattern(node.id);
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
- message: "'test' is an unused Props property."
2+
line: 7
3+
column: 8
4+
suggestions: null
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<script lang="ts">
2+
type Props = {
3+
test: string;
4+
'aria-label'?: string;
5+
};
6+
7+
const { 'aria-label': foo }: Props = $props();
8+
</script>
9+
10+
{foo}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
type Props = {
3+
test: string;
4+
'aria-label'?: string;
5+
};
6+
7+
const { test, 'aria-label': ariaLabel }: Props = $props();
8+
</script>
9+
10+
<h1>{test}</h1>
11+
<div aria-label={ariaLabel}>svelte/no-unused-props does not always respect aliases</div>

0 commit comments

Comments
 (0)