Skip to content

Commit 7cb3660

Browse files
authored
fix(no-unused-props): false positives for ComponentProps<any> (#1306)
1 parent 5c7cba3 commit 7cb3660

File tree

4 files changed

+42
-21
lines changed

4 files changed

+42
-21
lines changed

.changeset/strange-eagles-judge.md

Lines changed: 5 additions & 0 deletions
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): false positives for `ComponentProps<any>`

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

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { createRule } from '../utils/index.js';
2-
import { getTypeScriptTools } from '../utils/ts-utils/index.js';
2+
import { getTypeScriptTools, isAnyType } from '../utils/ts-utils/index.js';
33
import type { TSESTree } from '@typescript-eslint/types';
44
import type ts from 'typescript';
55
import { findVariable } from '../utils/ast-utils.js';
@@ -341,7 +341,9 @@ export default createRule('no-unused-props', {
341341
if (parentPath.length === 0) {
342342
const indexType = propsType.getStringIndexType();
343343
const numberIndexType = propsType.getNumberIndexType();
344-
const hasIndexSignature = Boolean(indexType) || Boolean(numberIndexType);
344+
const hasIndexSignature =
345+
Boolean(indexType && !isAnyType(indexType, tools!.ts)) ||
346+
Boolean(numberIndexType && !isAnyType(numberIndexType, tools!.ts));
345347

346348
if (hasIndexSignature && !hasRestElement(declaredPropertyNames)) {
347349
context.report({
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<script lang="ts">
2+
import type { ComponentProps } from 'svelte';
3+
4+
interface Props extends ComponentProps<any> {
5+
a: string;
6+
}
7+
8+
let { a }: Props = $props();
9+
</script>
10+
11+
<p>{a}</p>

packages/eslint-plugin-svelte/tests/utils/utils.ts

Lines changed: 22 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -69,11 +69,13 @@ export function getRuleFixturesRoot(ruleName: string): string {
6969
}
7070

7171
function fileNameSuffix(fileName: string): string {
72-
return fileName.match(/\.svelte\.(?:j|t)s$/u) ? fileName.slice(fileName.length - 10) : path.extname(fileName);
72+
return fileName.match(/\.svelte\.(?:j|t)s$/u)
73+
? fileName.slice(fileName.length - 10)
74+
: path.extname(fileName);
7375
}
7476

75-
function isSvelteFile(fileName): boolean {
76-
return fileName.match(/\.svelte(?:\.(?:j|t)s)?$/u);
77+
function isSvelteFile(fileName: string): boolean {
78+
return Boolean(fileName.match(/\.svelte(?:\.(?:j|t)s)?$/u));
7779
}
7880

7981
/**
@@ -230,13 +232,12 @@ function writeFixtures(
230232

231233
const config = getConfig(ruleName, inputFile);
232234

233-
const parser =
234-
isSvelteFile(inputFile)
235-
? svelteParser
236-
: path.extname(inputFile) === '.ts'
237-
? typescriptParser
238-
: undefined;
239-
const { code, filename, options, ...verifyConfig } = config;
235+
const parser = isSvelteFile(inputFile)
236+
? svelteParser
237+
: path.extname(inputFile) === '.ts'
238+
? typescriptParser
239+
: undefined;
240+
const { code, filename, options, only, ...verifyConfig } = config;
240241
const resolvedParser = verifyConfig.languageOptions?.parser ?? parser;
241242
const result = linter.verify(
242243
code,
@@ -251,7 +252,7 @@ function writeFixtures(
251252
},
252253
languageOptions: {
253254
globals: globals.browser,
254-
ecmaVersion:"latest",
255+
ecmaVersion: 'latest',
255256
sourceType: 'module',
256257
...verifyConfig?.languageOptions,
257258
parserOptions: {
@@ -320,12 +321,11 @@ function getConfig(ruleName: string, inputFile: string) {
320321
? require(configFile)
321322
: JSON.parse(fs.readFileSync(configFile, 'utf8'));
322323
}
323-
const parser =
324-
isSvelteFile(filename)
325-
? svelteParser
326-
: path.extname(inputFile) === '.ts'
327-
? typescriptParser
328-
: undefined;
324+
const parser = isSvelteFile(filename)
325+
? svelteParser
326+
: path.extname(inputFile) === '.ts'
327+
? typescriptParser
328+
: undefined;
329329

330330
const resolvedParser = config?.languageOptions?.parser
331331
? require(config.languageOptions.parser)
@@ -335,7 +335,7 @@ function getConfig(ruleName: string, inputFile: string) {
335335
...config,
336336
languageOptions: {
337337
globals: globals.browser,
338-
ecmaVersion:"latest",
338+
ecmaVersion: 'latest',
339339
sourceType: 'module',
340340
...config?.languageOptions,
341341
parserOptions: {
@@ -359,7 +359,10 @@ function getConfig(ruleName: string, inputFile: string) {
359359
}
360360

361361
function getRequirements(inputFile: string): Record<string, string> {
362-
let requirementsFile: string = inputFile.replace(/(input|\+.+)(?:\.[a-z]+)+$/u, 'requirements.json');
362+
let requirementsFile: string = inputFile.replace(
363+
/(input|\+.+)(?:\.[a-z]+)+$/u,
364+
'requirements.json'
365+
);
363366
if (!fs.existsSync(requirementsFile)) {
364367
requirementsFile = path.join(path.dirname(inputFile), '_requirements.json');
365368
}

0 commit comments

Comments
 (0)